diff --git a/app/views/alchemy/ingredients/_select_editor.html.erb b/app/views/alchemy/ingredients/_select_editor.html.erb
index 55f00dc511..957f0e2d9a 100644
--- a/app/views/alchemy/ingredients/_select_editor.html.erb
+++ b/app/views/alchemy/ingredients/_select_editor.html.erb
@@ -12,7 +12,7 @@
<%= warning(':select_values is nil',
"No select values given. Please provide select_values on the
- content definition settings in
+ ingredient definition settings in
elements.yml.") %>
<% else %>
<%
@@ -22,7 +22,7 @@
options_tags = options_for_select(select_values, select_editor.value)
end %>
<%= f.select :value, options_tags, {}, {
- id: nil,
+ id: select_editor.form_field_id,
class: ["alchemy_selectbox", "ingredient-editor-select"]
} %>
<% end %>
diff --git a/app/views/alchemy/ingredients/_text_editor.html.erb b/app/views/alchemy/ingredients/_text_editor.html.erb
index 5724c7dd77..1f88ad8dc2 100644
--- a/app/views/alchemy/ingredients/_text_editor.html.erb
+++ b/app/views/alchemy/ingredients/_text_editor.html.erb
@@ -7,7 +7,7 @@
<%= ingredient_label(text_editor) %>
<%= f.text_field :value,
class: text_editor.settings[:linkable] ? "text_with_icon" : "",
- id: nil,
+ id: text_editor.form_field_id,
type: text_editor.settings[:input_type] || "text" %>
<% if text_editor.settings[:anchor] %>
<%= render "alchemy/ingredients/shared/anchor", ingredient_editor: text_editor %>
diff --git a/app/views/alchemy/ingredients/shared/_link_tools.html.erb b/app/views/alchemy/ingredients/shared/_link_tools.html.erb
index bce06a6242..42d353b633 100644
--- a/app/views/alchemy/ingredients/shared/_link_tools.html.erb
+++ b/app/views/alchemy/ingredients/shared/_link_tools.html.erb
@@ -1,9 +1,9 @@
-
+
<%= link_to(
render_icon(:link),
'#',
onclick: 'new Alchemy.LinkDialog(this).open(); return false;',
- class: "icon_button#{ingredient_editor.linked? ? ' linked' : ''} link-essence",
+ class: "icon_button#{ingredient_editor.linked? ? ' linked' : ''} link-ingredient",
"data-parent-selector": "[data-ingredient-id='#{ingredient_editor.id}']",
title: Alchemy.t(:place_link),
id: "edit_link_#{ingredient_editor.id}"
@@ -12,7 +12,7 @@
render_icon(:unlink),
'#',
onclick: "return Alchemy.LinkDialog.removeLink(this, '[data-ingredient-id=\"#{ingredient_editor.id}\"]')",
- class: "icon_button unlink-essence #{ingredient_editor.linked? ? 'linked' : 'disabled'}",
+ class: "icon_button unlink-ingredient #{ingredient_editor.linked? ? 'linked' : 'disabled'}",
tabindex: ingredient_editor.linked? ? nil : '-1',
'data-ingredient-id' => ingredient_editor.id,
title: Alchemy.t(:unlink)
diff --git a/config/alchemy/config.yml b/config/alchemy/config.yml
index 1ba57bdc2c..a457f37178 100644
--- a/config/alchemy/config.yml
+++ b/config/alchemy/config.yml
@@ -66,9 +66,9 @@ items_per_page: 15
#
# Example:
# - name: some_element
-# contents:
-# - name: some_picture
-# type: EssencePicture
+# ingredients:
+# - role: some_picture
+# type: Picture
# settings:
# hint: true
# crop: true # turns on image cropping
@@ -82,7 +82,7 @@ items_per_page: 15
# preprocess_image_resize [String] # Use this option to resize images to the given size when they are uploaded to the image library. Downsizing example: '1000x1000>' (Default nil)
# image_output_format [String] # The global image output format setting. (Default +original+)
#
-# NOTE: You can always override the output format in the settings of your Essence in elements.yml, I.E. {format: 'gif'}
+# NOTE: You can always override the output format in the settings of your ingredients in elements.yml, I.E. {format: 'gif'}
#
output_image_jpg_quality: 85
preprocess_image_resize:
@@ -91,7 +91,7 @@ image_output_format: original
# This is used by the seeder to create the default site.
default_site:
name: Default Site
- host: '*'
+ host: "*"
# This is the default language when seeding.
default_language:
@@ -191,7 +191,7 @@ link_target_options: [blank]
# === Format matchers
#
# Named aliases for regular expressions that can be used in various places.
-# The most common use case is the format validation of essences, or attribute validations of your individual models.
+# The most common use case is the format validation of ingredients, or attribute validations of your individual models.
#
# == Example:
#
diff --git a/config/brakeman.ignore b/config/brakeman.ignore
index 08e9ae2dbf..1591ef3326 100644
--- a/config/brakeman.ignore
+++ b/config/brakeman.ignore
@@ -1,36 +1,5 @@
{
"ignored_warnings": [
- {
- "warning_type": "Cross-Site Scripting",
- "warning_code": 2,
- "fingerprint": "068b12d24047e2ece633115ba065ce46fc8c8a26827be7de2565ab721e1c2e82",
- "check_name": "CrossSiteScripting",
- "message": "Unescaped parameter value",
- "file": "app/views/alchemy/admin/elements/update.js.erb",
- "line": 21,
- "link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting",
- "code": "Element.find(params[:id]).ingredients_with_errors.map do\n \"[data-ingredient-id=\\\"#{ingredient.id}\\\"]\"\n end.join(\", \")",
- "render_path": [
- {
- "type": "controller",
- "class": "Alchemy::Admin::ElementsController",
- "method": "update",
- "line": 61,
- "file": "app/controllers/alchemy/admin/elements_controller.rb",
- "rendered": {
- "name": "alchemy/admin/elements/update",
- "file": "app/views/alchemy/admin/elements/update.js.erb"
- }
- }
- ],
- "location": {
- "type": "template",
- "template": "alchemy/admin/elements/update"
- },
- "user_input": "params[:id]",
- "confidence": "Weak",
- "note": ""
- },
{
"warning_type": "File Access",
"warning_code": 16,
@@ -102,26 +71,6 @@
"confidence": "Weak",
"note": ""
},
- {
- "warning_type": "Mass Assignment",
- "warning_code": 70,
- "fingerprint": "4b4dc24a6f5251bc1a6851597dfcee39608a2932eb7f81a4a241c00fca8a3043",
- "check_name": "MassAssignment",
- "message": "Specify exact keys allowed for mass assignment instead of using `permit!` which allows any keys",
- "file": "app/controllers/alchemy/admin/elements_controller.rb",
- "line": 155,
- "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
- "code": "params.fetch(:contents, {}).permit!",
- "render_path": null,
- "location": {
- "type": "method",
- "class": "Alchemy::Admin::ElementsController",
- "method": "contents_params"
- },
- "user_input": null,
- "confidence": "Medium",
- "note": "`Alchemy::Content` is a polymorphic association of any kind of model extending `Alchemy::Essence`. Since we can't know the attributes of all potential essences we need to permit all attributes. As this all happens inside the password protected /admin namespace this can be considered a false positive."
- },
{
"warning_type": "Command Injection",
"warning_code": 14,
diff --git a/config/locales/alchemy.en.yml b/config/locales/alchemy.en.yml
index f171dc76ba..130391e826 100644
--- a/config/locales/alchemy.en.yml
+++ b/config/locales/alchemy.en.yml
@@ -1,9 +1,7 @@
en:
-
# = Alchemy Translations
# All translations used in Alchemy CMS are inside this alchemy namespace.
alchemy:
-
# == Translations for page_layout names
# Just use the page_layouts name like defined inside the config/alchemy/page_layouts.yml file and translate it.
#
@@ -30,25 +28,24 @@ en:
#
element_names:
- # == Translated names for contents in elements.
- # Used for the content editor label inside the element editor view (The elements window)
+ # == Translated names for ingredients in elements.
+ # Used for the ingredient editor label inside the element editor view (The elements window)
#
- # Tip: You can translate content names globally for all contents of this name, or specificly for an element.
- # To do so, just place the content_name under the element name
+ # Tip: You can translate ingredient roles globally for all ingredients with this role, or specificly for an element.
+ # To do so, just place the ingredient role under the element name
#
# Example:
#
# en:
# alchemy:
- # content_names:
+ # ingredient_roles:
# headline: Headline
# news_article:
# headline: News Headline
# image_caption: Caption
# show_caption: Show Caption
#
- content_names:
-
+ ingredient_roles:
# === Translations for menu names
# Used for the translations of the names of root menu nodes.
@@ -141,37 +138,37 @@ en:
without_tag: Without tag
deletable: Not linked by file content
- # === Translations for content validations
- # Used when a user did not enter (correct) values to the content field.
+ # === Translations for ingredient validations
+ # Used when a user did not enter (correct) values to the ingredient field.
#
- # Tip: You can define the validation messages translations different for each element and content
+ # Tip: You can define the validation messages translations different for each element and ingredient
#
# Example:
#
# en:
# alchemy:
- # content_validations:
+ # ingredient_validations:
# contactform:
# success_page:
# blank: 'Please choose a follow up page.'
# mail_to:
# blank: 'Please provide an email address where the contact inquiries will be delivered to.'
#
- content_validations:
+ ingredient_validations:
errors:
blank: "%{field} can't be blank"
- invalid: '%{field} has wrong format'
- taken: '%{field} has already been taken'
+ invalid: "%{field} has wrong format"
+ taken: "%{field} has already been taken"
- default_content_texts:
+ default_ingredient_texts:
lorem: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
corporate_lorem: "Appropriately enable sustainable growth strategies vis-a-vis holistic materials. Energistically orchestrate open-source e-tailers vis-a-vis plug-and-play best practices. Uniquely plagiarize client-centric opportunities whereas plug-and-play ideas. Distinctively reconceptualize backward-compatible partnerships vis-a-vis reliable total linkage. Interactively fabricate highly efficient networks for clicks-and-mortar content. Collaboratively reconceptualize holistic markets via 2.0 architectures."
- essence_pictures:
+ picture_ingredients:
css_classes:
- left: 'Left from text'
- right: 'Right from text'
- no_float: 'Above the text'
+ left: "Left from text"
+ right: "Right from text"
+ no_float: "Above the text"
ingredient_values:
boolean:
@@ -181,32 +178,32 @@ en:
# == Contactform translations
contactform:
labels:
- salutation: 'Salutation'
- choose: 'Please choose'
- mr: 'Mr.'
- mrs: 'Mrs.'
- firstname: 'Firstname'
- lastname: 'Lastname'
- address: 'Street / No.'
- zip: 'Zipcode / City'
- phone: 'Telephone'
- email: 'Email'
- message: 'Message'
- send: 'Send'
- mandatory_fields: '*Mandatory fields.'
+ salutation: "Salutation"
+ choose: "Please choose"
+ mr: "Mr."
+ mrs: "Mrs."
+ firstname: "Firstname"
+ lastname: "Lastname"
+ address: "Street / No."
+ zip: "Zipcode / City"
+ phone: "Telephone"
+ email: "Email"
+ message: "Message"
+ send: "Send"
+ mandatory_fields: "*Mandatory fields."
# The flash message shown after successfully sending the message.
messages:
- success: 'Your message was delivered successfully.'
+ success: "Your message was delivered successfully."
# == Translated language names for translation select
translations:
- de: 'DE'
- en: 'EN'
- es: 'ES'
- it: 'IT'
- fr: 'FR'
- nl: 'NL'
- ru: 'RU'
+ de: "DE"
+ en: "EN"
+ es: "ES"
+ it: "IT"
+ fr: "FR"
+ nl: "NL"
+ ru: "RU"
# == User roles translations
user_roles:
@@ -227,18 +224,18 @@ en:
aliases: Enter additional domains this site should be accessible by. Please separate them by space or new line.
add_nested_element: "Add %{name}"
- anchor: 'Anchor'
+ anchor: "Anchor"
anchor_link_headline: You can link to an anchor from the current page.
automatic_anchor_notice: The anchor is generated automatically.
attribute_fixed: Value can't be changed for this page type
- back: 'back'
+ back: "back"
locked_pages: "Active pages"
"Add a page": "Add a page"
"Add global page": "Add global page"
"Add page link": "Add page link"
"Alchemy is open software and itself uses open software and free resources:": "Alchemy is open software and itself uses open software and free resources:"
- "Alchemy is up to date": 'Alchemy is up to date'
- 'An error happened': 'An error happened'
+ "Alchemy is up to date": "Alchemy is up to date"
+ "An error happened": "An error happened"
"Change password": "Change password"
"Choose page": "Choose page"
"Clear selection": "Clear selection"
@@ -252,7 +249,6 @@ en:
"Delete image": "Delete image"
"Delete element": "Delete element"
"Do you really want to clear the clipboard?": "Do you really want to clear the clipboard?"
- "Do you really want to delete this content?": "Do you really want to delete this content?"
"Drag an element over to the element window to restore it": "Drag an element over to the element window to restore it"
"Edit Picturemask": "Edit picturemask"
"Edit image": "Edit image"
@@ -318,11 +314,9 @@ en:
"Reload Preview": "Reload Preview"
"Remove item from clipboard": "Remove item from clipboard"
"Remove tag filter": "Remove tag filter"
- "Remove this content": "Remove this content"
"Reset Imagemask": "Reset mask"
"Reset password instructions": "Reset password instructions"
"Select all": "Select all"
- "Select an content": "Select a content"
"Select style": "Select style"
"Send reset instructions": "Send reset instructions"
show_elements: "Show Elements"
@@ -335,8 +329,6 @@ en:
"Site successfully removed": "Website successfully removed."
"Site successfully updated": "Website successfully updated."
"Size": "Size"
- "Successfully added content": "Successfully added %{content}"
- "Successfully deleted content": "Successfully deleted %{content}"
"Successfully deleted element": "Successfully deleted %{element}"
"Tags": "Tags"
"These pictures could not be deleted, because they were in use": "These pictures could not be deleted, because they were in use: %{names}"
@@ -351,9 +343,7 @@ en:
"Attachment Preview": "Attachment Preview"
"Visit page": "Visit page"
"Warning!": "Warning!"
- content_definition_missing: "Warning: Content is missing its definition. Please check the elements.yml"
- content_deprecated: "WARNING! This content is deprecated and will be removed soon. Please do not use it anymore."
- ingredient_deprecated: "WARNING! This content is deprecated and will be removed soon. Please do not use it anymore."
+ ingredient_deprecated: "WARNING! This field is deprecated and will be removed soon. Please do not use it anymore."
element_definition_missing: "WARNING! Missing element definition. Please check your elements.yml file."
element_deprecated: "WARNING! This element is deprecated and will be removed soon. Please do not use it anymore."
page_definition_missing: "WARNING! Missing page layout definition. Please check your page_layouts.yml file."
@@ -391,15 +381,13 @@ en:
confirm_to_delete_menu: "Do you really want to delete this menu?"
confirm_to_delete_node: "Do you really want to delete this menu node?"
confirm_to_delete_page: "Do you really want to delete this page?"
- content_essence_not_found: "Content essence not found"
- content_not_found: "Field for content not present."
- content_validations_headline: "Please check marked fields below"
+ ingredient_validations_headline: "Please check marked fields below"
copy: "copy"
copy_element: "Copy this element"
copy_page: "Copy page"
"Could not delete Pictures": "Could not delete Pictures"
copy_language_tree_heading: "Copy pages"
- country_code_placeholder: 'i.e. US (optional)'
+ country_code_placeholder: "i.e. US (optional)"
country_code_foot_note: "You only need to set a country code if you want to support multiple countries with the same language."
create: "create"
"Create language": "Create a new language"
@@ -416,7 +404,7 @@ en:
delete_menu: "Delete this menu"
delete_node: "Delete this menu node"
delete_page: "Delete this page"
- delete_tag: 'Delete tag'
+ delete_tag: "Delete tag"
document: "File"
download_csv: "Download CSV"
download_file: "Download file '%{filename}'"
@@ -429,13 +417,13 @@ en:
edit_node: "Edit menu node"
edit_page: "Edit this page"
edit_page_properties: "Edit page properties"
- edit_tag: 'Edit tag'
+ edit_tag: "Edit tag"
edit_selected_pictures: "Edit selected pictures"
element_editor_not_found: "Error within this Element"
element_of_type: "Element"
element_saved: "Saved element."
enter_external_link: "Please enter the URL you want to link with"
- explain_cropping: "
Move the frame and change its size with the mouse or arrow keys to adjust the image mask. Click on \"apply\" when you are satisfied with your selection.
If you want to return to the original centered image mask like it was defined in the layout, click \"reset\" and \"apply\" afterwards.
"
+ explain_cropping: '
Move the frame and change its size with the mouse or arrow keys to adjust the image mask. Click on "apply" when you are satisfied with your selection.
If you want to return to the original centered image mask like it was defined in the layout, click "reset" and "apply" afterwards.
'
explain_publishing: "Publish current page content"
explain_unlocking: "Leave page and unlock it for other users."
external_link_notice_1: "Please enter the complete url with http:// or a similar protocol."
@@ -474,7 +462,7 @@ en:
"item removed from clipboard": "Removed %{name} from clipboard"
javascript_disabled_headline: "Javascript is disabled!"
javascript_disabled_text: "Alchemy needs Javascript to run smoothly. Please enable it in your browser settings."
- language_code_placeholder: 'i.e. en'
+ language_code_placeholder: "i.e. en"
language_pages_copied: "Language tree successfully copied."
left: "left"
legacy_url_info_text: "A link is a redirect from an old URL to the current URL of this page. This redirect happens with a 301 status code."
@@ -529,10 +517,10 @@ en:
alchemy/site: "
You do not have any websites yet.
In order to serve requests you need to create a website first.
This form has been filled with sensible defaults that work in most cases.
"
no_search_results: "Your search did not return any results."
"not a valid image": "This is not an valid image."
- "or": 'or'
- or_replace_it_with_an_existing_tag: 'Or replace it with an existing tag'
+ "or": "or"
+ or_replace_it_with_an_existing_tag: "Or replace it with an existing tag"
"Page created": "Page: '%{name}' created."
- page_infos: 'Page info'
+ page_infos: "Page info"
page_properties: "Page properties"
page_public: "published"
page_published: "Published page"
@@ -567,26 +555,26 @@ en:
position_in_text: "Position in text"
preview_size: "Preview size"
preview_sizes:
- '240': '240px (small phone)'
- '320': '320px (iPhone)'
- '480': '480px (small Tablet)'
- '768': '768px (iPad - Portrait)'
- '1024': '1024px (iPad - Landscape)'
- '1280': '1280px (Desktop)'
+ "240": "240px (small phone)"
+ "320": "320px (iPhone)"
+ "480": "480px (small Tablet)"
+ "768": "768px (iPad - Portrait)"
+ "1024": "1024px (iPad - Landscape)"
+ "1280": "1280px (Desktop)"
preview_url: Preview
publish_page_language_not_public: Cannot publish page if language is not public
publish_page_not_allowed: You have not the permission to publish this page
- recently_uploaded_only: 'Recently uploaded only'
+ recently_uploaded_only: "Recently uploaded only"
"regular method": "Regular method"
remove: "Remove"
rename_file: "Rename this file."
rename: "Rename"
replace: replace
replace_file: Replace file
- 'Replaced Tag': "Tag '%{old_tag}' was replaced with '%{new_tag}'"
+ "Replaced Tag": "Tag '%{old_tag}' was replaced with '%{new_tag}'"
resources:
relation_select:
- blank: '- none -'
+ blank: "- none -"
right: "right"
robot_follow: "robot may follow links."
robot_index: "allow robot to index."
@@ -600,7 +588,7 @@ en:
show_eq: "Show EQ"
show_navigation: "Show in navigation"
show_page_in_sitemap: "Show page in sitemap."
- signup_mail_delivery_error: 'Signup mail could not be delivered. Please check your mail settings.'
+ signup_mail_delivery_error: "Signup mail could not be delivered. Please check your mail settings."
small_thumbnails: "Small thumbnails"
subject: "Subject"
successfully_added_element: "Successfully added new element."
@@ -610,7 +598,7 @@ en:
swap_image: "Change image"
insert_image: "Insert image"
tag_list: Tags
- tags_get_created_if_used_the_first_time: 'Tags get created if used the first time.'
+ tags_get_created_if_used_the_first_time: "Tags get created if used the first time."
this_picture_is_used_on_these_pages: "This picture is used on following pages"
title: "Title"
to_alchemy: "To Alchemy"
@@ -651,9 +639,9 @@ en:
"Successfully updated": "Successfully updated"
"Successfully removed": "Successfully removed"
"Nothing found": "Nothing found."
- complete: 'Abgeschlossen'
- "Update available": 'Update available'
- "Update status unavailable": 'Update status unavailable'
+ complete: "Abgeschlossen"
+ "Update available": "Update available"
+ "Update status unavailable": "Update status unavailable"
"Uploading": "Uploading"
cannot_signup_more_then_once: "You can't signup more then once."
confirm_to_delete_user: "Do you really want to delete this user?"
@@ -671,11 +659,11 @@ en:
# Simple form translations
forms:
- "yes": 'Yes'
- "no": 'No'
+ "yes": "Yes"
+ "no": "No"
required:
- text: 'required'
- mark: '*'
+ text: "required"
+ mark: "*"
error_notification:
default_message: "Please review the problems below:"
@@ -690,7 +678,7 @@ en:
formats:
alchemy:
default: "%m.%d.%Y %H:%M"
- essence_date: "%Y-%m-%d"
+ ingredient_date: "%Y-%m-%d"
page_status: "%m.%d.%Y %H:%M"
short_datetime: "%d %b %H:%M"
time: "%H:%M"
@@ -698,21 +686,19 @@ en:
# Translations for error messages.
errors:
models:
- alchemy/content:
- attributes:
- name:
- taken: 'is already taken in this element.'
- essence:
- validation_failed: 'Validation failed.'
alchemy/element:
attributes:
name:
blank: "^Please choose an element."
+ alchemy/ingredient:
+ attributes:
+ role:
+ taken: "is already taken in this element."
alchemy/language:
attributes:
language_code:
- invalid: '^Format of languagecode is not valid. Please use exactly two lowercase characters.'
- taken: 'is already taken for this country code.'
+ invalid: "^Format of languagecode is not valid. Please use exactly two lowercase characters."
+ taken: "is already taken for this country code."
locale:
missing_file: "Localization not found for given language code. Please choose an existing one."
alchemy/page:
@@ -739,28 +725,21 @@ en:
# Translations for Alchemy models
activemodel:
models:
- alchemy/essence_headline:
- one: Headline
- other: Headline
alchemy/message:
one: Message
other: Messages
alchemy/admin/preview_url: Internal
attributes:
- alchemy/essence_headline:
- body: Headline
- level: Level
- size: Size
alchemy/message:
- salutation: 'Salutation'
- firstname: 'Firstname'
- lastname: 'Lastname'
- address: 'Street / No.'
- zip: 'Zipcode'
+ salutation: "Salutation"
+ firstname: "Firstname"
+ lastname: "Lastname"
+ address: "Street / No."
+ zip: "Zipcode"
city: City
- phone: 'Telephone'
- email: 'Email'
- message: 'Message'
+ phone: "Telephone"
+ email: "Email"
+ message: "Message"
# Translations for Alchemy database models
activerecord:
@@ -769,7 +748,7 @@ en:
alchemy/node:
attributes:
base:
- essence_nodes_present: "This menu item is in use inside an Alchemy element on the following pages: %{page_names}."
+ node_ingredients_present: "This menu item is in use inside an Alchemy element on the following pages: %{page_names}."
alchemy/site:
attributes:
languages:
@@ -792,6 +771,9 @@ en:
alchemy/element:
one: "Element"
other: "Elements"
+ alchemy/ingredients/headline:
+ one: Headline
+ other: Headline
alchemy/legacy_page_url:
one: "Link"
other: "Links"
@@ -831,9 +813,15 @@ en:
name: "Name"
public: "visible"
tag_list: Tags
- alchemy/essence_file:
+ alchemy/ingredient:
+ dom_id: Anchor
+ alchemy/ingredients/file:
css_class: Style
- alchemy/essence_picture:
+ alchemy/ingredients/headline:
+ value: Headline
+ level: Level
+ size: Size
+ alchemy/ingredients/picture:
caption: "Caption"
title: "Title"
alt_tag: "Alternative text"
@@ -846,8 +834,6 @@ en:
crop_from: Crop from
crop_size: Crop size
picture_id: Bild
- alchemy/ingredient:
- dom_id: Anchor
alchemy/language:
country_code: "Country code"
language_code: "Language code"
diff --git a/config/routes.rb b/config/routes.rb
index ba60ca4cde..3879c9cad7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -16,8 +16,6 @@
end
namespace :admin, { path: Alchemy.admin_path, constraints: Alchemy.admin_constraints } do
- resources :contents, only: [:create]
-
resources :nodes
resources :pages do
@@ -41,7 +39,6 @@
end
resources :elements do
- resources :contents
collection do
post :order
end
@@ -73,20 +70,12 @@
end
end
- resources :essence_audios, only: [:edit, :update]
-
concern :croppable do
member do
get :crop
end
end
- resources :essence_pictures, only: [:edit, :update], concerns: [:croppable]
-
- resources :essence_files, only: [:edit, :update]
-
- resources :essence_videos, only: [:edit, :update]
-
resources :ingredients, only: [:edit, :update], concerns: [:croppable]
resources :legacy_page_urls
@@ -125,13 +114,9 @@
resources :elements, only: :show
namespace :api, defaults: { format: "json" } do
- resources :contents, only: [:index, :show]
resources :ingredients, only: [:index]
- resources :elements, only: [:index, :show] do
- get "/contents" => "contents#index", as: "contents"
- get "/contents/:name" => "contents#show", as: "content"
- end
+ resources :elements, only: [:index, :show]
resources :pages, only: [:index] do
get "elements" => "elements#index", as: "elements"
diff --git a/db/migrate/20200226213334_alchemy_four_point_four.rb b/db/migrate/20200226213334_alchemy_four_point_four.rb
index c37fe19467..16da133252 100644
--- a/db/migrate/20200226213334_alchemy_four_point_four.rb
+++ b/db/migrate/20200226213334_alchemy_four_point_four.rb
@@ -16,14 +16,6 @@ def up
end
end
- unless table_exists?("alchemy_contents")
- create_table "alchemy_contents" do |t|
- t.string "name"
- t.references "essence", null: false, polymorphic: true, index: { unique: true }
- t.references "element", null: false
- end
- end
-
unless table_exists?("alchemy_elements")
create_table "alchemy_elements" do |t|
t.string "name"
@@ -50,92 +42,6 @@ def up
end
end
- unless table_exists?("alchemy_essence_booleans")
- create_table "alchemy_essence_booleans" do |t|
- t.boolean "value"
- t.index ["value"], name: "index_alchemy_essence_booleans_on_value"
- end
- end
-
- unless table_exists?("alchemy_essence_dates")
- create_table "alchemy_essence_dates" do |t|
- t.datetime "date"
- end
- end
-
- unless table_exists?("alchemy_essence_files")
- create_table "alchemy_essence_files" do |t|
- t.references "attachment"
- t.string "title"
- t.string "css_class"
- t.string "link_text"
- end
- end
-
- unless table_exists?("alchemy_essence_htmls")
- create_table "alchemy_essence_htmls" do |t|
- t.text "source"
- end
- end
-
- unless table_exists?("alchemy_essence_links")
- create_table "alchemy_essence_links" do |t|
- t.string "link"
- t.string "link_title"
- t.string "link_target"
- t.string "link_class_name"
- end
- end
-
- unless table_exists?("alchemy_essence_pages")
- create_table "alchemy_essence_pages" do |t|
- t.references "page"
- end
- end
-
- unless table_exists?("alchemy_essence_pictures")
- create_table "alchemy_essence_pictures" do |t|
- t.references "picture"
- t.string "caption"
- t.string "title"
- t.string "alt_tag"
- t.string "link"
- t.string "link_class_name"
- t.string "link_title"
- t.string "css_class"
- t.string "link_target"
- t.string "crop_from"
- t.string "crop_size"
- t.string "render_size"
- end
- end
-
- unless table_exists?("alchemy_essence_richtexts")
- create_table "alchemy_essence_richtexts" do |t|
- t.text "body"
- t.text "stripped_body"
- t.boolean "public"
- end
- end
-
- unless table_exists?("alchemy_essence_selects")
- create_table "alchemy_essence_selects" do |t|
- t.string "value"
- t.index ["value"], name: "index_alchemy_essence_selects_on_value"
- end
- end
-
- unless table_exists?("alchemy_essence_texts")
- create_table "alchemy_essence_texts" do |t|
- t.text "body"
- t.string "link"
- t.string "link_title"
- t.string "link_class_name"
- t.boolean "public", default: false
- t.string "link_target"
- end
- end
-
unless table_exists?("alchemy_folded_pages")
create_table "alchemy_folded_pages" do |t|
t.references "page", null: false, index: false
@@ -262,18 +168,10 @@ def up
end
end
- unless foreign_key_exists?("alchemy_contents", column: "element_id")
- add_foreign_key "alchemy_contents", "alchemy_elements", column: "element_id", on_update: :cascade, on_delete: :cascade
- end
-
unless foreign_key_exists?("alchemy_elements", column: "page_id")
add_foreign_key "alchemy_elements", "alchemy_pages", column: "page_id", on_update: :cascade, on_delete: :cascade
end
- unless foreign_key_exists?("alchemy_essence_pages", column: "page_id")
- add_foreign_key "alchemy_essence_pages", "alchemy_pages", column: "page_id"
- end
-
unless foreign_key_exists?("alchemy_nodes", column: "language_id")
add_foreign_key "alchemy_nodes", "alchemy_languages", column: "language_id"
end
@@ -289,19 +187,8 @@ def up
def down
drop_table "alchemy_attachments" if table_exists?("alchemy_attachments")
- drop_table "alchemy_contents" if table_exists?("alchemy_contents")
drop_table "alchemy_elements" if table_exists?("alchemy_elements")
drop_table "alchemy_elements_alchemy_pages" if table_exists?("alchemy_elements_alchemy_pages")
- drop_table "alchemy_essence_booleans" if table_exists?("alchemy_essence_booleans")
- drop_table "alchemy_essence_dates" if table_exists?("alchemy_essence_dates")
- drop_table "alchemy_essence_files" if table_exists?("alchemy_essence_files")
- drop_table "alchemy_essence_htmls" if table_exists?("alchemy_essence_htmls")
- drop_table "alchemy_essence_links" if table_exists?("alchemy_essence_links")
- drop_table "alchemy_essence_pages" if table_exists?("alchemy_essence_pages")
- drop_table "alchemy_essence_pictures" if table_exists?("alchemy_essence_pictures")
- drop_table "alchemy_essence_richtexts" if table_exists?("alchemy_essence_richtexts")
- drop_table "alchemy_essence_selects" if table_exists?("alchemy_essence_selects")
- drop_table "alchemy_essence_texts" if table_exists?("alchemy_essence_texts")
drop_table "alchemy_folded_pages" if table_exists?("alchemy_folded_pages")
drop_table "alchemy_languages" if table_exists?("alchemy_languages")
drop_table "alchemy_legacy_page_urls" if table_exists?("alchemy_legacy_page_urls")
diff --git a/db/migrate/20200423073425_create_alchemy_essence_nodes.rb b/db/migrate/20200423073425_create_alchemy_essence_nodes.rb
deleted file mode 100644
index 50025e9ada..0000000000
--- a/db/migrate/20200423073425_create_alchemy_essence_nodes.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-class CreateAlchemyEssenceNodes < ActiveRecord::Migration[6.0]
- def change
- create_table :alchemy_essence_nodes do |t|
- t.references "node"
- t.timestamps
- end
- add_foreign_key "alchemy_essence_nodes", "alchemy_nodes", column: "node_id"
- end
-end
diff --git a/db/migrate/20200907111332_remove_tri_state_booleans.rb b/db/migrate/20200907111332_remove_tri_state_booleans.rb
index eccde1e34b..9ce50a2bbd 100644
--- a/db/migrate/20200907111332_remove_tri_state_booleans.rb
+++ b/db/migrate/20200907111332_remove_tri_state_booleans.rb
@@ -8,11 +8,6 @@ def change
change_column_null :alchemy_elements, :folded, false
change_column_null :alchemy_elements, :unique, false
- change_column_null :alchemy_essence_richtexts, :public, false, false
- change_column_default :alchemy_essence_richtexts, :public, false
-
- change_column_null :alchemy_essence_texts, :public, false
-
change_column_null :alchemy_folded_pages, :folded, false
change_column_null :alchemy_languages, :public, false
diff --git a/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb b/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb
deleted file mode 100644
index 4b558f6299..0000000000
--- a/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-class AddSanitizedBodyToAlchemyEssenceRichtexts < ActiveRecord::Migration[6.0]
- def change
- add_column :alchemy_essence_richtexts, :sanitized_body, :text
- end
-end
diff --git a/db/migrate/20210406093436_add_alchemy_essence_headlines.rb b/db/migrate/20210406093436_add_alchemy_essence_headlines.rb
deleted file mode 100644
index c8442b4ba3..0000000000
--- a/db/migrate/20210406093436_add_alchemy_essence_headlines.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-class AddAlchemyEssenceHeadlines < ActiveRecord::Migration[6.0]
- def change
- create_table :alchemy_essence_headlines do |t|
- t.text :body
- t.integer :level
- t.integer :size
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20210506135919_create_essence_audios.rb b/db/migrate/20210506135919_create_essence_audios.rb
deleted file mode 100644
index 47677a0fdf..0000000000
--- a/db/migrate/20210506135919_create_essence_audios.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-class CreateEssenceAudios < ActiveRecord::Migration[6.0]
- def up
- return if table_exists? :alchemy_essence_audios
-
- create_table :alchemy_essence_audios do |t|
- t.references :attachment
- t.boolean :controls, default: true, null: false
- t.boolean :autoplay, default: false
- t.boolean :loop, default: false, null: false
- t.boolean :muted, default: false, null: false
- end
- end
-
- def down
- drop_table :alchemy_essence_audios
- end
-end
diff --git a/db/migrate/20210506140258_create_essence_videos.rb b/db/migrate/20210506140258_create_essence_videos.rb
deleted file mode 100644
index d905e0d576..0000000000
--- a/db/migrate/20210506140258_create_essence_videos.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class CreateEssenceVideos < ActiveRecord::Migration[6.0]
- def up
- return if table_exists? :alchemy_essence_videos
-
- create_table :alchemy_essence_videos do |t|
- t.references :attachment
- t.string :width
- t.string :height
- t.boolean :allow_fullscreen, default: true, null: false
- t.boolean :autoplay, default: false, null: false
- t.boolean :controls, default: true, null: false
- t.boolean :loop, default: false, null: false
- t.boolean :muted, default: false, null: false
- t.string :preload
- end
- end
-
- def down
- drop_table :alchemy_essence_videos
- end
-end
diff --git a/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb b/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb
deleted file mode 100644
index 14d78dc5b4..0000000000
--- a/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AddPlaysinlineToAlchemyEssenceVideos < ActiveRecord::Migration[6.0]
- def change
- return if column_exists?(:alchemy_essence_videos, :playsinline)
-
- add_column :alchemy_essence_videos, :playsinline, :boolean, default: false, null: false
- end
-end
diff --git a/lib/alchemy.rb b/lib/alchemy.rb
index a506b2161c..20ddad5422 100644
--- a/lib/alchemy.rb
+++ b/lib/alchemy.rb
@@ -5,25 +5,6 @@
module Alchemy
YAML_PERMITTED_CLASSES = %w[Symbol Date Regexp]
- DEPRECATED_ESSENCE_CLASS_MAPPING = {
- "Alchemy::EssenceAudio" => "Alchemy::Ingredients::Audio",
- "Alchemy::EssenceBoolean" => "Alchemy::Ingredients::Boolean",
- "Alchemy::EssenceDate" => "Alchemy::Ingredients::Date",
- "Alchemy::EssenceFile" => "Alchemy::Ingredients::File",
- "Alchemy::EssenceHeadline" => "Alchemy::Ingredients::Headline",
- "Alchemy::EssenceHtml" => "Alchemy::Ingredients::Html",
- "Alchemy::EssenceLink" => "Alchemy::Ingredients::Link",
- "Alchemy::EssenceNode" => "Alchemy::Ingredients::Node",
- "Alchemy::EssencePage" => "Alchemy::Ingredients::Page",
- "Alchemy::EssencePicture" => "Alchemy::Ingredients::Picture",
- "Alchemy::EssenceRichtext" => "Alchemy::Ingredients::Richtext",
- "Alchemy::EssenceSelect" => "Alchemy::Ingredients::Select",
- "Alchemy::EssenceText" => "Alchemy::Ingredients::Text",
- "Alchemy::EssenceVideo" => "Alchemy::Ingredients::Video",
- }
-
- DEPRECATED_ESSENCE_CLASSES = DEPRECATED_ESSENCE_CLASS_MAPPING.keys
-
# Define page preview sources
#
# A preview source is a Ruby class returning an URL
diff --git a/lib/alchemy/cache_digests/template_tracker.rb b/lib/alchemy/cache_digests/template_tracker.rb
index d6f6aa7a88..3722f583a1 100644
--- a/lib/alchemy/cache_digests/template_tracker.rb
+++ b/lib/alchemy/cache_digests/template_tracker.rb
@@ -18,11 +18,10 @@ def dependencies
when /^alchemy\/page_layouts\/_(\w+)/
page_layout = PageLayout.get($1)
layout_elements = page_layout.fetch("elements", [])
- layout_elements.map { |name| "alchemy/elements/_#{name}_view" } +
- layout_elements.map { |name| "alchemy/elements/_#{name}" }
- when /^alchemy\/elements\/_(\w+)_view/, /^alchemy\/elements\/_(\w+)/
- essence_types($1).map { |name|
- "alchemy/essences/_#{name.underscore}_view"
+ layout_elements.map { |name| "alchemy/elements/_#{name}" }
+ when /^alchemy\/elements\/_(\w+)/
+ ingredient_types($1).map { |type|
+ "alchemy/ingredients/_#{type.underscore}_view"
}.uniq
else
ActionView::DependencyTracker::ERBTracker.call(@name, @template)
@@ -31,11 +30,11 @@ def dependencies
private
- def essence_types(name)
+ def ingredient_types(name)
element = Element.definitions.detect { |e| e["name"] == name }
return [] unless element
- element.fetch("contents", []).collect { |c| c["type"] }
+ element.fetch("ingredients", []).collect { |c| c["type"] }
end
end
end
diff --git a/lib/alchemy/deprecation.rb b/lib/alchemy/deprecation.rb
index 344759ab3f..a7864e1574 100644
--- a/lib/alchemy/deprecation.rb
+++ b/lib/alchemy/deprecation.rb
@@ -1,4 +1,4 @@
# frozen_string_literal: true
module Alchemy
- Deprecation = ActiveSupport::Deprecation.new("6.1", "Alchemy")
+ Deprecation = ActiveSupport::Deprecation.new("8.0", "Alchemy")
end
diff --git a/lib/alchemy/errors.rb b/lib/alchemy/errors.rb
index 1041aa8c07..079f81c8b5 100644
--- a/lib/alchemy/errors.rb
+++ b/lib/alchemy/errors.rb
@@ -3,10 +3,6 @@
# Custom error classes.
#
module Alchemy
- class ContentDefinitionError < StandardError
- # Raised if no content definition can be found.
- end
-
class DefaultLanguageNotFoundError < StandardError
# Raised if no default language configuration can be found.
def message
@@ -34,13 +30,6 @@ def message
end
end
- class EssenceMissingError < StandardError
- # Raised if a content misses its essence.
- def message
- "Essence not found"
- end
- end
-
# Raised if calling +image_file+ on a Picture object returns nil.
class MissingImageFileError < StandardError; end
diff --git a/lib/alchemy/essence.rb b/lib/alchemy/essence.rb
deleted file mode 100644
index d329d6891b..0000000000
--- a/lib/alchemy/essence.rb
+++ /dev/null
@@ -1,250 +0,0 @@
-# frozen_string_literal: true
-
-require "active_record"
-
-module Alchemy #:nodoc:
- module Essence #:nodoc:
- def self.included(base)
- base.extend(ClassMethods)
- end
-
- # Delivers various methods we need for Essences in Alchemy.
- #
- # To turn a model into an essence call acts_as_essence inside your model and you will get:
- # * validations
- # * several getters (ie: page, element, content, ingredient, preview_text)
- #
- module ClassMethods
- # Turn any active record model into an essence by calling this class method
- #
- # @option options [String || Symbol] ingredient_column ('body')
- # specifies the column name you use for storing the content in the database (default: +body+)
- # @option options [String || Symbol] validate_column (ingredient_column)
- # The column the the validations run against.
- # @option options [String || Symbol] preview_text_column (ingredient_column)
- # Specify the column for the preview_text method.
- # @deprecated
- def acts_as_essence(options = {})
- if !DEPRECATED_ESSENCE_CLASSES.include?(name)
- Alchemy::Deprecation.warn "Please create a custom Alchemy::Ingredient for #{name} instead"
- end
-
- register_as_essence_association!
-
- configuration = {
- ingredient_column: "body",
- }.update(options)
-
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
- attr_writer :validation_errors
- include Alchemy::Essence::InstanceMethods
-
- validate :validate_ingredient, on: :update, if: -> { validations.any? }
-
- has_one :content, as: :essence, class_name: "Alchemy::Content", inverse_of: :essence
- has_one :element, through: :content, class_name: "Alchemy::Element"
- has_one :page, through: :element, class_name: "Alchemy::Page"
-
- scope :available, -> { joins(:element).merge(Alchemy::Element.published) }
- scope :from_element, ->(name) { joins(:element).where(Element.table_name => { name: name }) }
-
- delegate :restricted?, to: :page, allow_nil: true
- delegate :public?, to: :element, allow_nil: true
-
- after_update :touch_element
-
- def acts_as_essence_class
- #{name}
- end
-
- def ingredient_column
- '#{configuration[:ingredient_column]}'
- end
-
- def validation_column
- '#{configuration[:validate_column] || configuration[:ingredient_column]}'
- end
-
- def preview_text_column
- '#{configuration[:preview_text_column] || configuration[:ingredient_column]}'
- end
- RUBY
-
- if configuration[:belongs_to]
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
- belongs_to :ingredient_association, **#{configuration[:belongs_to]}
-
- alias_method :#{configuration[:ingredient_column]}, :ingredient_association
- alias_method :#{configuration[:ingredient_column]}=, :ingredient_association=
- RUBY
- end
- end
-
- private
-
- # Register the current class as has_many association on +Alchemy::Page+ and +Alchemy::Element+ models
- def register_as_essence_association!
- klass_name = model_name.to_s
- arguments = [:has_many, klass_name.demodulize.tableize.to_sym]
- kwargs = { through: :contents, source: :essence, source_type: klass_name }
- %w(Page Element).each { |k| "Alchemy::#{k}".constantize.send(*arguments, **kwargs) }
- end
- end
-
- module InstanceMethods
- # Essence Validations:
- #
- # Essence validations can be set inside the config/elements.yml file.
- #
- # Supported validations are:
- #
- # * presence
- # * uniqueness
- # * format
- #
- # format needs to come with a regex or a predefined matcher string as its value.
- # There are already predefined format matchers listed in the config/alchemy/config.yml file.
- # It is also possible to add own format matchers there.
- #
- # Example of format matchers in config/alchemy/config.yml:
- #
- # format_matchers:
- # email: !ruby/regexp '/\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/'
- # url: !ruby/regexp '/\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?\z/ix'
- # ssl: !ruby/regexp '/https:\/\/[\S]+/'
- #
- # Example of an element definition with essence validations:
- #
- # - name: person
- # contents:
- # - name: name
- # type: EssenceText
- # validate: [presence]
- # - name: email
- # type: EssenceText
- # validate: [format: 'email']
- # - name: homepage
- # type: EssenceText
- # validate: [format: !ruby/regexp '^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$']
- #
- # Example of an element definition with chained validations.
- #
- # - name: person
- # contents:
- # - name: name
- # type: EssenceText
- # validate: [presence, uniqueness, format: 'name']
- #
- def validate_ingredient
- validations.each do |validation|
- if validation.respond_to?(:keys)
- validation.map do |key, value|
- send("validate_#{key}", value)
- end
- else
- send("validate_#{validation}")
- end
- end
- end
-
- def validations
- @validations ||= definition.present? ? definition["validate"] || [] : []
- end
-
- def validation_errors
- @validation_errors ||= []
- end
-
- def validate_presence(validate = true)
- if validate && ingredient.blank?
- errors.add(ingredient_column, :blank)
- validation_errors << :blank
- end
- end
-
- def validate_uniqueness(validate = true)
- return if !validate || !public?
-
- if duplicates.any?
- errors.add(ingredient_column, :taken)
- validation_errors << :taken
- end
- end
-
- def validate_format(format)
- matcher = Config.get("format_matchers")[format] || format
- if ingredient.to_s.match(Regexp.new(matcher)).nil?
- errors.add(ingredient_column, :invalid)
- validation_errors << :invalid
- end
- end
-
- def duplicates
- acts_as_essence_class
- .available
- .from_element(element.name)
- .where(ingredient_column.to_s => ingredient)
- .where.not(id: id)
- end
-
- # Returns the value stored from the database column that is configured as ingredient column.
- def ingredient
- if respond_to?(ingredient_column)
- send(ingredient_column)
- end
- end
-
- # Sets the value stored in the database column that is configured as ingredient column.
- def ingredient=(value)
- if respond_to?(ingredient_setter_method)
- send(ingredient_setter_method, value)
- end
- end
-
- # Returns the setter method for ingredient column
- def ingredient_setter_method
- ingredient_column.to_s + "="
- end
-
- # Essence definition from config/elements.yml
- def definition
- return {} if element.nil? || element.content_definitions.nil?
-
- element.content_definitions.detect { |c| c["name"] == content.name } || {}
- end
-
- # Touches element. Called after save.
- def touch_element
- element&.touch
- end
-
- # Returns the first x (default 30) characters of ingredient for the Element#preview_text method.
- #
- def preview_text(maxlength = 30)
- send(preview_text_column).to_s[0..maxlength - 1]
- end
-
- def open_link_in_new_window?
- respond_to?(:link_target) && link_target == "blank"
- end
-
- def partial_name
- self.class.name.split("::").last.underscore
- end
-
- def acts_as_essence?
- acts_as_essence_class.present?
- end
-
- def to_partial_path
- "alchemy/essences/#{partial_name}_view"
- end
-
- def has_tinymce?
- false
- end
- end
- end
-end
-
-ActiveRecord::Base.include(Alchemy::Essence)
diff --git a/lib/alchemy/hints.rb b/lib/alchemy/hints.rb
index d548c4e0ff..48eb2c584c 100644
--- a/lib/alchemy/hints.rb
+++ b/lib/alchemy/hints.rb
@@ -4,7 +4,7 @@ module Alchemy
module Hints
# Returns a hint
#
- # To add a hint to a content pass +hint: true+ to the element definition in its element.yml
+ # To add a hint to a ingredient pass +hint: true+ to the element definition in its element.yml
#
# Then the hint itself is placed in the locale yml files.
#
@@ -14,23 +14,23 @@ module Hints
#
# # elements.yml
# - name: headline
- # contents:
- # - name: headline
- # type: EssenceText
- # hint: true
+ # ingredients:
+ # - role: headline
+ # type: Text
+ # hint: true
#
# # config/locales/de.yml
# de:
- # content_hints:
+ # ingredient_hints:
# headline: Lorem ipsum
#
# == Hint Key Example:
#
# - name: headline
- # contents:
- # - name: headline
- # type: EssenceText
- # hint: Lorem ipsum
+ # ingredients:
+ # - role: headline
+ # type: Text
+ # hint: Lorem ipsum
#
# @return String
#
diff --git a/lib/alchemy/permissions.rb b/lib/alchemy/permissions.rb
index b0bb62443c..b0a954586e 100644
--- a/lib/alchemy/permissions.rb
+++ b/lib/alchemy/permissions.rb
@@ -37,10 +37,6 @@ module GuestUser
def alchemy_guest_user_rules
can([:show, :download], Alchemy::Attachment) { |a| !a.restricted? }
- can :read, Alchemy::Content, Alchemy::Content.available.not_restricted do |c|
- c.public? && !c.restricted?
- end
-
can :read, Alchemy::Element, Alchemy::Element.published.not_restricted do |e|
e.public? && !e.restricted?
end
@@ -64,10 +60,6 @@ def alchemy_member_rules
# Resources
can [:show, :download], Alchemy::Attachment
- can :read, Alchemy::Content, Alchemy::Content.available do |c|
- c.public?
- end
-
can :read, Alchemy::Element, Alchemy::Element.published do |e|
e.public?
end
@@ -109,12 +101,7 @@ def alchemy_author_rules
# Resources
can [:read, :download], Alchemy::Attachment
- can :manage, Alchemy::Content
can :manage, Alchemy::Element
- can :manage, Alchemy::EssenceAudio
- can :manage, Alchemy::EssenceFile
- can :manage, Alchemy::EssencePicture
- can :manage, Alchemy::EssenceVideo
can :manage, Alchemy::Ingredient
can [:crop], Alchemy::Ingredients::Picture
can :manage, Alchemy::LegacyPageUrl
diff --git a/lib/alchemy/tasks/tidy.rb b/lib/alchemy/tasks/tidy.rb
index 5d43e4d3ca..cc8e1976fb 100644
--- a/lib/alchemy/tasks/tidy.rb
+++ b/lib/alchemy/tasks/tidy.rb
@@ -25,25 +25,6 @@ def update_element_positions
end
end
- def update_content_positions
- Alchemy::Element.all.each do |element|
- if element.contents.any?
- puts "\n## Updating content positions of element `#{element.name}`"
- end
- element.contents.group_by(&:element_id).each do |_, contents|
- contents.each_with_index do |content, idx|
- position = idx + 1
- if content.position != position
- log "Updating position for content ##{content.id} to #{position}"
- content.update_column(:position, position)
- else
- log "Position for content ##{content.id} is already correct (#{position})", :skip
- end
- end
- end
- end
- end
-
def remove_orphaned_elements
puts "\n## Removing orphaned elements"
elements = Alchemy::Element.unscoped.not_nested
@@ -79,25 +60,6 @@ def remove_trashed_elements
end
end
- def remove_orphaned_contents
- puts "\n## Removing orphaned contents"
- contents = Alchemy::Content.unscoped.all
- if contents.any?
- orphaned_contents = contents.select do |content|
- content.essence.nil? && content.essence_id.present? ||
- content.element.nil? && content.element_id.present?
- end
- if orphaned_contents.any?
- log "Found #{orphaned_contents.size} orphaned contents"
- destroy_orphaned_records(orphaned_contents, "content")
- else
- log "No orphaned contents found", :skip
- end
- else
- log "No contents found", :skip
- end
- end
-
def remove_duplicate_legacy_urls
puts "\n## Removing duplicate legacy URLs"
sql = <<~SQL
diff --git a/lib/alchemy/test_support/essence_shared_examples.rb b/lib/alchemy/test_support/essence_shared_examples.rb
deleted file mode 100644
index a89907151e..0000000000
--- a/lib/alchemy/test_support/essence_shared_examples.rb
+++ /dev/null
@@ -1,271 +0,0 @@
-# frozen_string_literal: true
-
-require "shoulda-matchers"
-
-RSpec.shared_examples_for "an essence" do
- let(:element) { Alchemy::Element.new }
- let(:content) { Alchemy::Content.new(name: "foo") }
- let(:content_definition) { { "name" => "foo" } }
-
- it "touches the element after save" do
- element = FactoryBot.create(:alchemy_element)
- content = FactoryBot.create(:alchemy_content, element: element, essence: essence, essence_type: essence.class.name)
-
- element.update_column(:updated_at, 3.days.ago)
- content.essence.update(essence.ingredient_column.to_sym => ingredient_value)
-
- element.reload
- expect(element.updated_at).to be_within(3.seconds).of(Time.current)
- end
-
- it "should have correct partial path" do
- underscored_essence = essence.class.name.demodulize.underscore
- expect(essence.to_partial_path).to eq("alchemy/essences/#{underscored_essence}_view")
- end
-
- describe "#definition" do
- subject { essence.definition }
-
- context "without element" do
- it { is_expected.to eq({}) }
- end
-
- context "with element" do
- before do
- expect(essence).to receive(:element).at_least(:once).and_return(element)
- end
-
- context "but without content definitions" do
- it { is_expected.to eq({}) }
- end
-
- context "and content definitions" do
- before do
- allow(essence).to receive(:content).and_return(content)
- end
-
- context "containing the content name" do
- before do
- expect(element).to receive(:content_definitions).at_least(:once).and_return([content_definition])
- end
-
- it "returns the content definition" do
- is_expected.to eq(content_definition)
- end
- end
-
- context "not containing the content name" do
- before do
- expect(element).to receive(:content_definitions).at_least(:once).and_return([])
- end
-
- it { is_expected.to eq({}) }
- end
- end
- end
- end
-
- describe "#ingredient=" do
- it "should set the value to ingredient column" do
- essence.ingredient = ingredient_value
- expect(essence.ingredient).to eq ingredient_value
- end
- end
-
- describe "validations" do
- context "without essence definition in elements.yml" do
- it "should return an empty array" do
- allow(essence).to receive(:definition).and_return nil
- expect(essence.validations).to eq([])
- end
- end
-
- context "without validations defined in essence definition in elements.yml" do
- it "should return an empty array" do
- allow(essence).to receive(:definition).and_return({ name: "test", type: "EssenceText" })
- expect(essence.validations).to eq([])
- end
- end
-
- describe "presence" do
- context "with string given as validation type" do
- before do
- allow(essence).to receive(:definition).and_return({ "validate" => ["presence"] })
- end
-
- context "when the ingredient column is empty" do
- before do
- essence.update(essence.ingredient_column.to_sym => nil)
- end
-
- it "should not be valid" do
- expect(essence).to_not be_valid
- end
- end
-
- context "when the ingredient column is not nil" do
- before do
- essence.update(essence.ingredient_column.to_sym => ingredient_value)
- end
-
- it "should be valid" do
- expect(essence).to be_valid
- end
- end
- end
-
- context "with hash given as validation type" do
- context "where the value is true" do
- before do
- allow(essence).to receive(:definition).and_return({ "validate" => [{ "presence" => true }] })
- end
-
- context "when the ingredient column is empty" do
- before do
- essence.update(essence.ingredient_column.to_sym => nil)
- end
-
- it "should not be valid" do
- expect(essence).to_not be_valid
- end
- end
-
- context "when the ingredient column is not nil" do
- before do
- essence.update(essence.ingredient_column.to_sym => ingredient_value)
- end
-
- it "should be valid" do
- expect(essence).to be_valid
- end
- end
- end
-
- context "where the value is false" do
- before do
- allow(essence).to receive(:definition).and_return({ "validate" => [{ "presence" => false }] })
- end
-
- it "should be valid" do
- expect(essence).to be_valid
- end
- end
- end
- end
-
- describe "uniqueness" do
- before do
- allow(essence).to receive(:element).and_return(FactoryBot.create(:alchemy_element))
- essence.update(essence.ingredient_column.to_sym => ingredient_value)
- end
-
- context "with string given as validation type" do
- before do
- expect(essence).to receive(:definition).at_least(:once).and_return({ "validate" => ["uniqueness"] })
- end
-
- context "when a duplicate exists" do
- before do
- allow(essence).to receive(:duplicates).and_return([essence.dup])
- end
-
- it "should not be valid" do
- expect(essence).to_not be_valid
- end
-
- context "when validated essence is not public" do
- before do
- expect(essence).to receive(:public?).and_return(false)
- end
-
- it "should be valid" do
- expect(essence).to be_valid
- end
- end
- end
-
- context "when no duplicate exists" do
- before do
- expect(essence).to receive(:duplicates).and_return([])
- end
-
- it "should be valid" do
- expect(essence).to be_valid
- end
- end
- end
-
- context "with hash given as validation type" do
- context "where the value is true" do
- before do
- expect(essence).to receive(:definition).at_least(:once).and_return({ "validate" => [{ "uniqueness" => true }] })
- end
-
- context "when a duplicate exists" do
- before do
- allow(essence).to receive(:duplicates).and_return([essence.dup])
- end
-
- it "should not be valid" do
- expect(essence).to_not be_valid
- end
-
- context "when validated essence is not public" do
- before do
- expect(essence).to receive(:public?).and_return(false)
- end
-
- it "should be valid" do
- expect(essence).to be_valid
- end
- end
- end
-
- context "when no duplicate exists" do
- before do
- expect(essence).to receive(:duplicates).and_return([])
- end
-
- it "should be valid" do
- expect(essence).to be_valid
- end
- end
- end
-
- context "where the value is false" do
- before do
- allow(essence).to receive(:definition).and_return({ "validate" => [{ "uniqueness" => false }] })
- end
-
- it "should be valid" do
- expect(essence).to be_valid
- end
- end
- end
- end
-
- describe "#acts_as_essence?" do
- it "should return true" do
- expect(essence.acts_as_essence?).to be_truthy
- end
- end
- end
-
- context "delegations" do
- it { should delegate_method(:restricted?).to(:page) }
- it { should delegate_method(:public?).to(:element) }
- end
-
- describe "essence relations" do
- let(:page) { FactoryBot.create(:alchemy_page, :restricted) }
- let(:element) { FactoryBot.create(:alchemy_element) }
-
- it "registers itself on page as essence relation" do
- expect(page.respond_to?(essence.class.model_name.route_key)).to be(true)
- end
-
- it "registers itself on element as essence relation" do
- expect(element.respond_to?(essence.class.model_name.route_key)).to be(true)
- end
- end
-end
diff --git a/lib/alchemy/test_support/factories/content_factory.rb b/lib/alchemy/test_support/factories/content_factory.rb
deleted file mode 100644
index 514aad0db9..0000000000
--- a/lib/alchemy/test_support/factories/content_factory.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :alchemy_content, class: "Alchemy::Content" do
- name { "text" }
- essence_type { "Alchemy::EssenceText" }
- association :essence, factory: :alchemy_essence_text
- association :element, factory: :alchemy_element
-
- trait :essence_file do
- essence_type { "Alchemy::EssenceFile" }
- association :essence, factory: :alchemy_essence_file
- end
-
- trait :essence_picture do
- essence_type { "Alchemy::EssencePicture" }
- association :essence, factory: :alchemy_essence_picture
- end
- end
-end
diff --git a/lib/alchemy/test_support/factories/element_factory.rb b/lib/alchemy/test_support/factories/element_factory.rb
index 7db7670c46..69908f55b6 100644
--- a/lib/alchemy/test_support/factories/element_factory.rb
+++ b/lib/alchemy/test_support/factories/element_factory.rb
@@ -3,7 +3,6 @@
FactoryBot.define do
factory :alchemy_element, class: "Alchemy::Element" do
name { "article" }
- autogenerate_contents { false }
autogenerate_ingredients { false }
association :page_version, factory: :alchemy_page_version
@@ -26,12 +25,7 @@
name { "slide" }
end
- trait :with_contents do
- autogenerate_contents { true }
- end
-
trait :with_ingredients do
- name { "element_with_ingredients" }
autogenerate_ingredients { true }
end
end
diff --git a/lib/alchemy/test_support/factories/essence_audio_factory.rb b/lib/alchemy/test_support/factories/essence_audio_factory.rb
deleted file mode 100644
index 71a22abe0a..0000000000
--- a/lib/alchemy/test_support/factories/essence_audio_factory.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :alchemy_essence_audio, class: "Alchemy::EssenceAudio" do
- attachment factory: :alchemy_attachment
- end
-end
diff --git a/lib/alchemy/test_support/factories/essence_file_factory.rb b/lib/alchemy/test_support/factories/essence_file_factory.rb
deleted file mode 100644
index 82f11e0f7c..0000000000
--- a/lib/alchemy/test_support/factories/essence_file_factory.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :alchemy_essence_file, class: "Alchemy::EssenceFile" do
- attachment factory: :alchemy_attachment
- end
-end
diff --git a/lib/alchemy/test_support/factories/essence_page_factory.rb b/lib/alchemy/test_support/factories/essence_page_factory.rb
deleted file mode 100644
index b44fc67602..0000000000
--- a/lib/alchemy/test_support/factories/essence_page_factory.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :alchemy_essence_page, class: "Alchemy::EssencePage" do
- page factory: :alchemy_page
- end
-end
diff --git a/lib/alchemy/test_support/factories/essence_picture_factory.rb b/lib/alchemy/test_support/factories/essence_picture_factory.rb
deleted file mode 100644
index f7d56bd71f..0000000000
--- a/lib/alchemy/test_support/factories/essence_picture_factory.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :alchemy_essence_picture, class: "Alchemy::EssencePicture" do
- picture factory: :alchemy_picture
-
- trait :with_content do
- association :content, factory: :alchemy_content
- end
- end
-end
diff --git a/lib/alchemy/test_support/factories/essence_text_factory.rb b/lib/alchemy/test_support/factories/essence_text_factory.rb
deleted file mode 100644
index a093182962..0000000000
--- a/lib/alchemy/test_support/factories/essence_text_factory.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :alchemy_essence_text, class: "Alchemy::EssenceText" do
- body { "This is a headline" }
- end
-end
diff --git a/lib/alchemy/test_support/factories/essence_video_factory.rb b/lib/alchemy/test_support/factories/essence_video_factory.rb
deleted file mode 100644
index 75032f0f29..0000000000
--- a/lib/alchemy/test_support/factories/essence_video_factory.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :alchemy_essence_video, class: "Alchemy::EssenceVideo" do
- attachment factory: :alchemy_attachment
- end
-end
diff --git a/lib/alchemy/test_support/factories/ingredient_factory.rb b/lib/alchemy/test_support/factories/ingredient_factory.rb
index 907e8bcffa..d8615e224d 100644
--- a/lib/alchemy/test_support/factories/ingredient_factory.rb
+++ b/lib/alchemy/test_support/factories/ingredient_factory.rb
@@ -19,7 +19,7 @@
factory :"alchemy_ingredient_#{ingredient}", class: "Alchemy::Ingredients::#{ingredient.classify}" do
role { ingredient }
type { "Alchemy::Ingredients::#{ingredient.classify}" }
- association :element, name: "all_you_can_eat_ingredients", factory: :alchemy_element
+ association :element, name: "all_you_can_eat", factory: :alchemy_element
end
end
end
diff --git a/lib/alchemy/test_support/factories/page_factory.rb b/lib/alchemy/test_support/factories/page_factory.rb
index 3b50dd0972..221b578888 100644
--- a/lib/alchemy/test_support/factories/page_factory.rb
+++ b/lib/alchemy/test_support/factories/page_factory.rb
@@ -42,10 +42,12 @@
after(:create) do |page|
if page.autogenerate_elements
page.definition["autogenerate"].each do |name|
- create(:alchemy_element,
+ create(
+ :alchemy_element,
name: name,
page_version: page.public_version,
- autogenerate_contents: true)
+ autogenerate_ingredients: true,
+ )
end
end
end
diff --git a/lib/alchemy/test_support/shared_dom_ids_examples.rb b/lib/alchemy/test_support/shared_dom_ids_examples.rb
index 282d25166b..54f5aa8df9 100644
--- a/lib/alchemy/test_support/shared_dom_ids_examples.rb
+++ b/lib/alchemy/test_support/shared_dom_ids_examples.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.shared_examples_for "having dom ids" do
- let(:element) { build(:alchemy_element, name: "element_with_ingredients") }
+ let(:element) { build(:alchemy_element, name: "article") }
let(:ingredient) do
described_class.new(
diff --git a/lib/alchemy/test_support/shared_ingredient_examples.rb b/lib/alchemy/test_support/shared_ingredient_examples.rb
index 8f7e548226..dc3996d3c9 100644
--- a/lib/alchemy/test_support/shared_ingredient_examples.rb
+++ b/lib/alchemy/test_support/shared_ingredient_examples.rb
@@ -3,7 +3,7 @@
require "shoulda-matchers"
RSpec.shared_examples_for "an alchemy ingredient" do
- let(:element) { build(:alchemy_element, name: "element_with_ingredients") }
+ let(:element) { build(:alchemy_element, name: "article") }
subject(:ingredient) do
described_class.new(
diff --git a/lib/alchemy/tinymce.rb b/lib/alchemy/tinymce.rb
index 236bc08e5d..8387def590 100644
--- a/lib/alchemy/tinymce.rb
+++ b/lib/alchemy/tinymce.rb
@@ -35,11 +35,7 @@ def init
end
def custom_configs_present?(page)
- custom_config_contents(page).any? || custom_config_ingredients(page).any?
- end
-
- def custom_config_contents(page)
- content_definitions_from_elements(page.descendent_element_definitions)
+ custom_config_ingredients(page).any?
end
def custom_config_ingredients(page)
@@ -48,19 +44,6 @@ def custom_config_ingredients(page)
private
- def content_definitions_from_elements(definitions)
- definitions.collect do |el|
- next if el["contents"].blank?
-
- contents = el["contents"].select do |c|
- c["settings"] && c["settings"]["tinymce"].is_a?(Hash)
- end
- next if contents.blank?
-
- contents.map { |c| c.merge("element" => el["name"]) }
- end.flatten.compact
- end
-
def ingredient_definitions_from_elements(definitions)
definitions.collect do |el|
next if el["ingredients"].blank?
diff --git a/lib/alchemy/upgrader/six_point_zero.rb b/lib/alchemy/upgrader/six_point_zero.rb
index e8384615ce..0a4900273e 100644
--- a/lib/alchemy/upgrader/six_point_zero.rb
+++ b/lib/alchemy/upgrader/six_point_zero.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require_relative "tasks/add_page_versions"
-require_relative "tasks/ingredients_migrator"
module Alchemy
class Upgrader::SixPointZero < Upgrader
@@ -10,12 +9,6 @@ def create_public_page_versions
desc "Create public page versions for pages"
Alchemy::Upgrader::Tasks::AddPageVersions.new.create_public_page_versions
end
-
- def create_ingredients
- desc "Create ingredients for elements with ingredients defined"
- Alchemy::Upgrader::Tasks::IngredientsMigrator.new.create_ingredients
- log "Done.", :success
- end
end
end
end
diff --git a/lib/alchemy/upgrader/tasks/ingredients_migrator.rb b/lib/alchemy/upgrader/tasks/ingredients_migrator.rb
deleted file mode 100644
index 1ebf2fafbf..0000000000
--- a/lib/alchemy/upgrader/tasks/ingredients_migrator.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-require "alchemy/upgrader"
-
-module Alchemy::Upgrader::Tasks
- class IngredientsMigrator < Thor
- include Thor::Actions
-
- no_tasks do
- def create_ingredients(verbose: !Rails.env.test?)
- Alchemy::Deprecation.silence do
- elements_with_ingredients = Alchemy::ElementDefinition.all.select { |d| d.key?(:ingredients) }
- if ENV["ONLY"]
- elements_with_ingredients = elements_with_ingredients.select { |d| d[:name].in? ENV["ONLY"].split(",") }
- end
- # eager load all elements that have ingredients defined but no ingredient records yet.
- all_elements = Alchemy::Element
- .named(elements_with_ingredients.map { |d| d[:name] })
- .preload(contents: :essence)
- .left_outer_joins(:ingredients).where(alchemy_ingredients: { id: nil })
- .to_a
- elements_with_ingredients.map do |element_definition|
- elements = all_elements.select { |e| e.name == element_definition[:name] }
- if elements.any?
- puts "-- Creating ingredients for #{elements.count} #{element_definition[:name]}(s)" if verbose
- elements.each do |element|
- MigrateElementIngredients.call(element)
- print "." if verbose
- end
- puts "\n" if verbose
- elsif verbose
- puts "-- No #{element_definition[:name]} elements found for migration."
- end
- end
- end
- end
- end
-
- class MigrateElementIngredients
- def self.call(element)
- Alchemy::Element.transaction do
- element.definition[:ingredients].each do |ingredient_definition|
- ingredient = element.ingredients.build(
- role: ingredient_definition[:role],
- type: Alchemy::Ingredient.normalize_type(ingredient_definition[:type]),
- )
-
- content = element.content_by_name(ingredient_definition[:role])
- if content
- essence = content.essence
- if essence
- belongs_to_associations = essence.class.reflect_on_all_associations(:belongs_to)
- if belongs_to_associations.any?
- ingredient.related_object = essence.public_send(belongs_to_associations.first.name)
- else
- ingredient.value = content.ingredient
- end
- data = ingredient.class.stored_attributes.fetch(:data, []).each_with_object({}) do |attr, d|
- next unless essence.respond_to?(attr)
-
- d[attr] = essence.public_send(attr)
- end
- ingredient.data = data
- end
- content.destroy!
- end
-
- ingredient.save!
- end
- end
- end
- end
- end
-end
diff --git a/lib/alchemy_cms.rb b/lib/alchemy_cms.rb
index 4e94e43f50..5aa95ca467 100644
--- a/lib/alchemy_cms.rb
+++ b/lib/alchemy_cms.rb
@@ -39,7 +39,6 @@
require_relative "alchemy/elements_finder"
require_relative "alchemy/error_tracking"
require_relative "alchemy/errors"
-require_relative "alchemy/essence"
require_relative "alchemy/filetypes"
require_relative "alchemy/forms/builder"
require_relative "alchemy/hints"
diff --git a/lib/generators/alchemy/elements/elements_generator.rb b/lib/generators/alchemy/elements/elements_generator.rb
index d2123ab497..aff65b0b38 100644
--- a/lib/generators/alchemy/elements/elements_generator.rb
+++ b/lib/generators/alchemy/elements/elements_generator.rb
@@ -13,7 +13,6 @@ def create_partials
@elements.each do |element|
@element = element
- @contents = element["contents"] || []
@ingredients = element["ingredients"] || []
@element_name = element_name(element)
conditional_template "view.html.#{template_engine}", "#{elements_dir}/_#{@element_name}.html.#{template_engine}"
diff --git a/lib/generators/alchemy/elements/templates/view.html.erb b/lib/generators/alchemy/elements/templates/view.html.erb
index 1c7f659c62..82f70fa414 100644
--- a/lib/generators/alchemy/elements/templates/view.html.erb
+++ b/lib/generators/alchemy/elements/templates/view.html.erb
@@ -1,14 +1,5 @@
<%%- cache(<%= @element_name %>) do -%>
<%%= element_view_for(<%= @element_name %>) do |el| -%>
- <%- @contents.each do |content| -%>
- <%- if @contents.length > 1 -%>
-
">
- <%%= el.render :<%= content["name"] %> %>
-
- <%- else -%>
- <%%= el.render :<%= content["name"] %> %>
- <%- end -%>
- <%- end -%>
<%- @ingredients.each do |ingredient| -%>
<%- if @ingredients.length > 1 -%>
">
diff --git a/lib/generators/alchemy/elements/templates/view.html.haml b/lib/generators/alchemy/elements/templates/view.html.haml
index 3b3e943ea7..57365fc855 100644
--- a/lib/generators/alchemy/elements/templates/view.html.haml
+++ b/lib/generators/alchemy/elements/templates/view.html.haml
@@ -1,13 +1,5 @@
- cache(<%= @element_name -%>) do
= element_view_for(<%= @element_name -%>) do |el|
- <%- @contents.each do |content| -%>
- <%- if @contents.length > 1 -%>
- .<%= content["name"] %>
- = el.render :<%= content["name"] %>
- <%- else -%>
- = el.render :<%= content["name"] %>
- <%- end -%>
- <%- end -%>
<%- @ingredients.each do |ingredient| -%>
<%- if @ingredients.length > 1 -%>
.<%= ingredient["role"] %>
diff --git a/lib/generators/alchemy/elements/templates/view.html.slim b/lib/generators/alchemy/elements/templates/view.html.slim
index 3b3e943ea7..57365fc855 100644
--- a/lib/generators/alchemy/elements/templates/view.html.slim
+++ b/lib/generators/alchemy/elements/templates/view.html.slim
@@ -1,13 +1,5 @@
- cache(<%= @element_name -%>) do
= element_view_for(<%= @element_name -%>) do |el|
- <%- @contents.each do |content| -%>
- <%- if @contents.length > 1 -%>
- .<%= content["name"] %>
- = el.render :<%= content["name"] %>
- <%- else -%>
- = el.render :<%= content["name"] %>
- <%- end -%>
- <%- end -%>
<%- @ingredients.each do |ingredient| -%>
<%- if @ingredients.length > 1 -%>
.<%= ingredient["role"] %>
diff --git a/lib/generators/alchemy/essence/essence_generator.rb b/lib/generators/alchemy/essence/essence_generator.rb
deleted file mode 100644
index 8946856ba8..0000000000
--- a/lib/generators/alchemy/essence/essence_generator.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-require "rails"
-
-module Alchemy
- module Generators
- class EssenceGenerator < ::Rails::Generators::Base
- desc "This generator generates an Alchemy essence for you."
- argument :essence_name, banner: "YourEssenceName"
- source_root File.expand_path("templates", __dir__)
-
- def init
- @essence_name = essence_name.underscore
- @essence_view_path = "app/views/alchemy/essences"
- end
-
- def create_model
- invoke("model", [@essence_name])
- end
-
- def act_as_essence
- essence_class_file = "app/models/#{@essence_name}.rb"
- essence_class = @essence_name.classify
- inject_into_class essence_class_file, essence_class, <<~CLASSMETHOD
- acts_as_essence(
- # Your options:
- #
- # ingredient_column: [String or Symbol] - Specifies the column name you use for storing the content in the database. (Default :body)
- # validate_column: [String or Symbol] - Which column should be validated. (Default: ingredient_column)
- # preview_text_column: [String or Symbol] - Specifies the column for the preview_text method. (Default: ingredient_column)
- # preview_text_method: [String or Symbol] - A method called on ingredient to get the preview text. (Default: ingredient_column)
- )
- CLASSMETHOD
- end
-
- def copy_templates
- essence_name = @essence_name.classify.demodulize.underscore
- @essence_editor_local = "#{essence_name}_editor"
- template "view.html.erb", "#{@essence_view_path}/_#{essence_name}_view.html.erb"
- template "editor.html.erb", "#{@essence_view_path}/_#{essence_name}_editor.html.erb"
- end
-
- def show_todo
- say "\nPlease open the generated migration file and add your columns to your table."
- say "Then run 'rake db:migrate' to update your database."
- say "Also check the generated view files and alter them to fit your needs."
- end
- end
- end
-end
diff --git a/lib/generators/alchemy/essence/templates/editor.html.erb b/lib/generators/alchemy/essence/templates/editor.html.erb
deleted file mode 100644
index cbdcfd85a8..0000000000
--- a/lib/generators/alchemy/essence/templates/editor.html.erb
+++ /dev/null
@@ -1,17 +0,0 @@
-<%%#
- Available locals:
- * <%= @essence_editor_local %> - A Alchemy::ContentEditor instance
-
- Please consult Alchemy::Content.rb docs for further methods on the content object
-%>
-<%%= content_tag :div,
- id: <%= @essence_editor_local %>.dom_id,
- class: <%= @essence_editor_local %>.css_classes,
- data: <%= @essence_editor_local %>.data_attributes do %>
- <%%= content_label(<%= @essence_editor_local %>) %>
- <%%= text_field_tag(
- <%= @essence_editor_local %>.form_field_name,
- <%= @essence_editor_local %>.ingredient,
- id: <%= @essence_editor_local %>.form_field_id
- ) %>
-<%% end %>
diff --git a/lib/generators/alchemy/essence/templates/view.html.erb b/lib/generators/alchemy/essence/templates/view.html.erb
deleted file mode 100644
index caea7e7a38..0000000000
--- a/lib/generators/alchemy/essence/templates/view.html.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<%%# The content object holds the essence %>
-<%%= content.ingredient %>
diff --git a/lib/generators/alchemy/install/files/alchemy.en.yml b/lib/generators/alchemy/install/files/alchemy.en.yml
index a325f62f8a..9757ebd0b1 100644
--- a/lib/generators/alchemy/install/files/alchemy.en.yml
+++ b/lib/generators/alchemy/install/files/alchemy.en.yml
@@ -1,6 +1,5 @@
en:
alchemy:
-
# Translations for page layout names
page_layout_names:
index: Homepage
@@ -9,23 +8,23 @@ en:
element_names:
article: Article
- # Translations for content names
- content_names:
+ # Translations for ingredient roles
+ ingredient_roles:
headline: Headline
text: Text
picture: Picture
- # Default texts for new contents created
- default_content_texts:
+ # Default texts for new ingredients created
+ default_ingredient_texts:
article_headline: "Welcome to your first Alchemy CMS page"
- article_text: '
How to get started.
First of all you should read about Alchemy and its architecture in the guidelines.
The most important things to know about Alchemy are elements and page layouts.
Elements:
With Alchemy you can split pages into content parts, elements. These elements can be defined out of several base content types: essences. The basic essences are:
EssenceText - A single line of text
EssenceRichtext - A TinyMCE powered formatted text block
EssencePicture - A reference to an image
EssenceHtml - HTML embed code
EssenceSelect - A selection of values
EssenceBoolean - A checkbox
Elements get defined in a YAML file config/alchemy/elements.yml
You can define several types of pages, called page layouts. You can assign elements to page layouts and control how elements and the page of a certain layout behave.
Page layouts get defined in a YAML file config/alchemy/page_layouts.yml
First of all you should read about Alchemy and its architecture in the guidelines.
The most important things to know about Alchemy are elements and page layouts.
Elements:
With Alchemy you can split pages into content parts, elements. These elements can be defined out of several base content types: ingredients. The ingredients are:
Text - A single line of text
Richtext - A TinyMCE powered formatted text block
Picture - A reference to an image
Html - HTML embed code
Select - A selection of values
Boolean - A checkbox
Elements get defined in a YAML file config/alchemy/elements.yml
You can define several types of pages, called page layouts. You can assign elements to page layouts and control how elements and the page of a certain layout behave.
Page layouts get defined in a YAML file config/alchemy/page_layouts.yml
'
# Hint texts for elements
element_hints:
article: "This is a hint text for the article element. You can change this text in `config/locales/alchemy.en.yml`. Feel free to change it as you like, it's yours."
- # Hint texts for contents
- content_hints:
+ # Hint texts for ingredients
+ ingredient_hints:
headline: "This is a single line of unformatable Text"
picture: "Pictures are stored in the library. You can assign a picture multiple times throughout your site. Alchemy has an image cropper build right in."
text: "This is a rich text block powered by TinyMCE editor. You can change the configuration of the editor. See http://guides.alchemy-cms.com/customize_tinymce.html"
diff --git a/lib/generators/alchemy/install/templates/elements.yml.tt b/lib/generators/alchemy/install/templates/elements.yml.tt
index 4e98abdbec..dc4af8057e 100644
--- a/lib/generators/alchemy/install/templates/elements.yml.tt
+++ b/lib/generators/alchemy/install/templates/elements.yml.tt
@@ -6,16 +6,16 @@
- name: article
hint: true
unique: true
- contents:
- - name: headline
- type: EssenceText
- default: :article_headline
- hint: true
- - name: picture
- type: EssencePicture
- hint: true
- - name: text
- type: EssenceRichtext
- default: :article_text
- hint: true
+ ingredients:
+ - role: headline
+ type: Text
+ default: :article_headline
+ hint: true
+ - role: picture
+ type: Picture
+ hint: true
+ - role: text
+ type: Richtext
+ default: :article_text
+ hint: true
<%- end -%>
diff --git a/lib/tasks/alchemy/thumbnails.rake b/lib/tasks/alchemy/thumbnails.rake
index a4fe6355b2..2cfc6a1a98 100644
--- a/lib/tasks/alchemy/thumbnails.rake
+++ b/lib/tasks/alchemy/thumbnails.rake
@@ -2,10 +2,9 @@
namespace :alchemy do
namespace :generate do
- desc "Generates all thumbnails for Alchemy Pictures and EssencePictures."
+ desc "Generates all thumbnails for Alchemy Pictures and Picture Ingredients."
task thumbnails: [
"alchemy:generate:picture_thumbnails",
- "alchemy:generate:essence_picture_thumbnails",
"alchemy:generate:ingredient_picture_thumbnails",
]
@@ -23,24 +22,6 @@ namespace :alchemy do
puts "Done!"
end
- desc "Generates thumbnails for Alchemy EssencePictures."
- task essence_picture_thumbnails: :environment do
- essence_pictures = Alchemy::EssencePicture.joins(:content, :ingredient_association)
- puts "Regenerate #{essence_pictures.count} essence picture thumbnails."
- puts "Please wait..."
-
- essence_pictures.find_each do |essence_picture|
- puts essence_picture.picture_url
- puts essence_picture.thumbnail_url
-
- essence_picture.settings.fetch(:srcset, []).each do |src|
- puts essence_picture.picture_url(src)
- end
- end
-
- puts "Done!"
- end
-
desc "Generates thumbnails for Alchemy Picture Ingredients (set ELEMENTS=element1,element2 to only generate thumbnails for a subset of elements)."
task ingredient_picture_thumbnails: :environment do
ingredient_pictures = Alchemy::Ingredients::Picture.
diff --git a/lib/tasks/alchemy/tidy.rake b/lib/tasks/alchemy/tidy.rake
index e0300c93c4..4bdc1658c2 100644
--- a/lib/tasks/alchemy/tidy.rake
+++ b/lib/tasks/alchemy/tidy.rake
@@ -17,15 +17,9 @@ namespace :alchemy do
Alchemy::Tidy.update_element_positions
end
- desc "Fixes content positions."
- task content_positions: [:environment] do
- Alchemy::Tidy.update_content_positions
- end
-
- desc "Remove orphaned records (elements & contents)."
+ desc "Remove orphaned records (elements)."
task remove_orphaned_records: [:environment] do
Rake::Task["alchemy:tidy:remove_orphaned_elements"].invoke
- Rake::Task["alchemy:tidy:remove_orphaned_contents"].invoke
end
desc "Remove orphaned elements."
@@ -33,11 +27,6 @@ namespace :alchemy do
Alchemy::Tidy.remove_orphaned_elements
end
- desc "Remove orphaned contents."
- task remove_orphaned_contents: [:environment] do
- Alchemy::Tidy.remove_orphaned_contents
- end
-
desc "Remove trashed elements."
task remove_trashed_elements: [:environment] do
Alchemy::Tidy.remove_trashed_elements
diff --git a/spec/controllers/alchemy/admin/attachments_controller_spec.rb b/spec/controllers/alchemy/admin/attachments_controller_spec.rb
index 0713fc5842..aaa98e76db 100644
--- a/spec/controllers/alchemy/admin/attachments_controller_spec.rb
+++ b/spec/controllers/alchemy/admin/attachments_controller_spec.rb
@@ -35,9 +35,9 @@ module Alchemy
context "when params[:form_field_id]" do
context "is set" do
it "it renders the archive_overlay partial" do
- get :index, params: { form_field_id: "contents_1_attachment_id" }
+ get :index, params: { form_field_id: "element_1_ingredient_1_attachment_id" }
expect(response).to render_template(partial: "_archive_overlay")
- expect(assigns(:form_field_id)).to eq("contents_1_attachment_id")
+ expect(assigns(:form_field_id)).to eq("element_1_ingredient_1_attachment_id")
end
end
@@ -226,9 +226,9 @@ module Alchemy
let(:attachment) { create(:alchemy_attachment) }
it "assigns a assignable_id" do
- put :assign, params: { form_field_id: "contents_1_attachment_id", id: attachment.id }, xhr: true
+ put :assign, params: { form_field_id: "element_1_ingredient_1_attachment_id", id: attachment.id }, xhr: true
expect(assigns(:assignable_id)).to eq(attachment.id.to_s)
- expect(assigns(:form_field_id)).to eq("contents_1_attachment_id")
+ expect(assigns(:form_field_id)).to eq("element_1_ingredient_1_attachment_id")
end
end
end
diff --git a/spec/controllers/alchemy/admin/elements_controller_spec.rb b/spec/controllers/alchemy/admin/elements_controller_spec.rb
index c607968874..94c5d73e65 100644
--- a/spec/controllers/alchemy/admin/elements_controller_spec.rb
+++ b/spec/controllers/alchemy/admin/elements_controller_spec.rb
@@ -192,7 +192,7 @@ module Alchemy
context "with ingredient validations" do
subject do
- post :create, params: { element: { page_version_id: page_version.id, name: "all_you_can_eat_ingredients" } }, xhr: true
+ post :create, params: { element: { page_version_id: page_version.id, name: "all_you_can_eat" } }, xhr: true
end
it "creates element without error" do
@@ -206,41 +206,6 @@ module Alchemy
expect(Element).to receive(:find).at_least(:once).and_return(element)
end
- context "with element having contents" do
- subject do
- put :update, params: { id: element.id, element: element_params, contents: contents_params }.compact, xhr: true
- end
-
- let(:element) { create(:alchemy_element, :with_contents) }
- let(:content) { element.contents.first }
- let(:element_params) { { tag_list: "Tag 1", public: false } }
- let(:contents_params) { { content.id => { ingredient: "Title" } } }
-
- it "updates all contents in element" do
- expect { subject }.to change { content.reload.ingredient }.to("Title")
- end
-
- it "updates the element" do
- expect { subject }.to change { element.tag_list }.to(["Tag 1"])
- end
-
- context "failed validations" do
- it "displays validation failed notice" do
- expect(element).to receive(:update_contents).and_return(false)
- subject
- expect(assigns(:element_validated)).to be_falsey
- end
- end
-
- context "with element not taggable" do
- let(:element_params) { nil }
-
- it "updates the element" do
- expect { subject }.to_not raise_error
- end
- end
- end
-
context "with element having ingredients" do
subject do
put :update, params: { id: element.id, element: element_params }, xhr: true
diff --git a/spec/controllers/alchemy/admin/essence_audios_controller_spec.rb b/spec/controllers/alchemy/admin/essence_audios_controller_spec.rb
deleted file mode 100644
index d191fd6c29..0000000000
--- a/spec/controllers/alchemy/admin/essence_audios_controller_spec.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-RSpec.describe Alchemy::Admin::EssenceAudiosController do
- routes { Alchemy::Engine.routes }
-
- before do
- authorize_user(:as_author)
- end
-
- let(:essence_audio) { mock_model("Alchemy::EssenceAudio", attachment: nil, content: content) }
- let(:content) { mock_model("Alchemy::Content") }
- let(:attachment) { mock_model("Alchemy::Attachment") }
-
- describe "#edit" do
- before do
- expect(Alchemy::EssenceAudio).to receive(:find).with(essence_audio.id.to_s) { essence_audio }
- end
-
- it "assigns @essence_audio with the Alchemy::EssenceAudio found by id" do
- get :edit, params: { id: essence_audio.id }
- expect(assigns(:essence_audio)).to eq(essence_audio)
- end
- end
-
- describe "#update" do
- let(:essence_audio) { create(:alchemy_essence_audio) }
-
- let(:params) do
- {
- id: essence_audio.id,
- essence_audio: {
- autoplay: false,
- controls: true,
- loop: false,
- muted: true,
- },
- }
- end
-
- before do
- expect(Alchemy::EssenceAudio).to receive(:find) { essence_audio }
- end
-
- it "should update the attributes of essence_audio" do
- put :update, params: params, xhr: true
- expect(essence_audio.autoplay).to eq false
- expect(essence_audio.controls).to eq true
- expect(essence_audio.loop).to eq false
- expect(essence_audio.muted).to eq true
- end
- end
-end
diff --git a/spec/controllers/alchemy/admin/essence_files_controller_spec.rb b/spec/controllers/alchemy/admin/essence_files_controller_spec.rb
deleted file mode 100644
index 5123a48baa..0000000000
--- a/spec/controllers/alchemy/admin/essence_files_controller_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-module Alchemy
- describe Admin::EssenceFilesController do
- routes { Alchemy::Engine.routes }
-
- before do
- authorize_user(:as_admin)
- end
-
- let(:essence_file) { mock_model("EssenceFile", :attachment= => nil, content: content) }
- let(:content) { mock_model("Content") }
- let(:attachment) { mock_model("Attachment") }
-
- describe "#edit" do
- before do
- expect(EssenceFile).to receive(:find).with(essence_file.id.to_s) { essence_file }
- end
-
- it "assigns @essence_file with the EssenceFile found by id" do
- get :edit, params: { id: essence_file.id }
- expect(assigns(:essence_file)).to eq(essence_file)
- end
-
- it "should assign @content with essence_file's content" do
- get :edit, params: { id: essence_file.id }
- expect(assigns(:content)).to eq(content)
- end
- end
-
- describe "#update" do
- let(:essence_file) { create(:alchemy_essence_file) }
-
- let(:params) do
- {
- id: essence_file.id,
- essence_file: {
- title: "new title",
- css_class: "left",
- link_text: "Download this file",
- },
- }
- end
-
- before do
- expect(EssenceFile).to receive(:find) { essence_file }
- end
-
- it "should update the attributes of essence_file" do
- put :update, params: params, xhr: true
- expect(essence_file.title).to eq "new title"
- expect(essence_file.css_class).to eq "left"
- expect(essence_file.link_text).to eq "Download this file"
- end
- end
- end
-end
diff --git a/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb b/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb
deleted file mode 100644
index 18ac49faf6..0000000000
--- a/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-module Alchemy
- describe Admin::EssencePicturesController do
- routes { Alchemy::Engine.routes }
-
- before { authorize_user(:as_admin) }
-
- let(:essence) { EssencePicture.new(content: content, picture: picture) }
- let(:content) { Content.new }
- let(:picture) { Picture.new }
-
- describe "#edit" do
- before do
- expect(EssencePicture).to receive(:find).and_return(essence)
- expect(Content).to receive(:find).and_return(content)
- end
-
- it "should assign @essence_picture and @content instance variables" do
- post :edit, params: { id: 1, content_id: 1 }
- expect(assigns(:essence_picture)).to be_a(EssencePicture)
- expect(assigns(:content)).to be_a(Content)
- end
- end
-
- it_behaves_like "having crop action", model_class: Alchemy::EssencePicture do
- let(:croppable_resource) { essence }
- end
-
- describe "#update" do
- before do
- expect(EssencePicture).to receive(:find).and_return(essence)
- expect(Content).to receive(:find).and_return(content)
- end
-
- let(:attributes) do
- {
- render_size: "1x1",
- alt_tag: "Alt Tag",
- caption: "Caption",
- css_class: "CSS Class",
- title: "Title",
- }
- end
-
- it "updates the essence attributes" do
- expect(essence).to receive(:update).and_return(true)
- put :update, params: { id: 1, essence_picture: attributes }, xhr: true
- end
-
- it "saves the cropping mask" do
- expect(essence).to receive(:update).and_return(true)
- put :update, params: {
- id: 1,
- essence_picture: {
- render_size: "1x1",
- crop_from: "0x0",
- crop_size: "100x100",
- },
- }, xhr: true
- end
- end
- end
-end
diff --git a/spec/controllers/alchemy/admin/essence_videos_controller_spec.rb b/spec/controllers/alchemy/admin/essence_videos_controller_spec.rb
deleted file mode 100644
index c32299c53e..0000000000
--- a/spec/controllers/alchemy/admin/essence_videos_controller_spec.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-RSpec.describe Alchemy::Admin::EssenceVideosController do
- routes { Alchemy::Engine.routes }
-
- before do
- authorize_user(:as_author)
- end
-
- let(:essence_video) { mock_model("Alchemy::EssenceVideo", attachment: nil, content: content) }
- let(:content) { mock_model("Alchemy::Content") }
- let(:attachment) { mock_model("Alchemy::Attachment") }
-
- describe "#edit" do
- before do
- expect(Alchemy::EssenceVideo).to receive(:find).with(essence_video.id.to_s) { essence_video }
- end
-
- it "assigns @essence_video with the Alchemy::EssenceVideo found by id" do
- get :edit, params: { id: essence_video.id }
- expect(assigns(:essence_video)).to eq(essence_video)
- end
- end
-
- describe "#update" do
- let(:essence_video) { create(:alchemy_essence_video) }
-
- let(:params) do
- {
- id: essence_video.id,
- essence_video: {
- width: "200",
- height: "150",
- autoplay: false,
- controls: true,
- loop: false,
- muted: true,
- preload: "auto",
- },
- }
- end
-
- before do
- expect(Alchemy::EssenceVideo).to receive(:find) { essence_video }
- end
-
- it "should update the attributes of essence_video" do
- put :update, params: params, xhr: true
- expect(essence_video.width).to eq "200"
- expect(essence_video.height).to eq "150"
- expect(essence_video.autoplay).to eq false
- expect(essence_video.controls).to eq true
- expect(essence_video.loop).to eq false
- expect(essence_video.muted).to eq true
- expect(essence_video.preload).to eq "auto"
- end
- end
-end
diff --git a/spec/controllers/alchemy/admin/ingredients_controller_spec.rb b/spec/controllers/alchemy/admin/ingredients_controller_spec.rb
index ba3d6499cd..0495506c10 100644
--- a/spec/controllers/alchemy/admin/ingredients_controller_spec.rb
+++ b/spec/controllers/alchemy/admin/ingredients_controller_spec.rb
@@ -6,7 +6,7 @@
routes { Alchemy::Engine.routes }
let(:attachment) { build_stubbed(:alchemy_attachment) }
- let(:element) { build(:alchemy_element, name: "all_you_can_eat_ingredients") }
+ let(:element) { build(:alchemy_element, name: "all_you_can_eat") }
let(:ingredient) do
stub_model(
diff --git a/spec/controllers/alchemy/admin/pictures_controller_spec.rb b/spec/controllers/alchemy/admin/pictures_controller_spec.rb
index 785d98b399..f90da0ccde 100644
--- a/spec/controllers/alchemy/admin/pictures_controller_spec.rb
+++ b/spec/controllers/alchemy/admin/pictures_controller_spec.rb
@@ -109,12 +109,12 @@ module Alchemy
context "when params[:form_field_id]" do
context "is set" do
it "for html requests it renders the archive_overlay partial" do
- get :index, params: { form_field_id: "contents_1_picture_id" }
+ get :index, params: { form_field_id: "element_1_ingredient_1_picture_id" }
expect(response).to render_template(partial: "_archive_overlay")
end
it "for ajax requests it renders the archive_overlay template" do
- get :index, params: { form_field_id: "contents_1_picture_id" }, xhr: true
+ get :index, params: { form_field_id: "element_1_ingredient_1_picture_id" }, xhr: true
expect(response).to render_template(:archive_overlay)
end
end
@@ -168,12 +168,11 @@ module Alchemy
context "with assignments" do
let!(:page) { create(:alchemy_page) }
let!(:element) { create(:alchemy_element, page: page) }
- let!(:content) { create(:alchemy_content, element: element) }
- let!(:essence) { create(:alchemy_essence_picture, content: content, picture: picture) }
+ let!(:ingredient) { create(:alchemy_ingredient_picture, element: element, related_object: picture) }
- it "assigns all essence pictures having an assignment to @assignments" do
+ it "assigns all picture ingredients having an assignment to @assignments" do
get :show, params: { id: picture.id }
- expect(assigns(:assignments)).to eq([essence])
+ expect(assigns(:assignments)).to eq([ingredient])
end
end
@@ -387,7 +386,7 @@ module Alchemy
end
context "in overlay" do
- let(:params) { { form_field_id: "contents_1_picture_id", size: size } }
+ let(:params) { { form_field_id: "element_1_ingredient_1_picture_id", size: size } }
context "with params[:size] set to medium" do
let(:size) { "medium" }
@@ -449,9 +448,9 @@ module Alchemy
let(:picture) { create(:alchemy_picture) }
it "assigns a assignable_id" do
- put :assign, params: { form_field_id: "contents_1_picture_id", id: picture.id }, xhr: true
+ put :assign, params: { form_field_id: "element_1_ingredient_1_picture_id", id: picture.id }, xhr: true
expect(assigns(:assignable_id)).to eq(picture.id.to_s)
- expect(assigns(:form_field_id)).to eq("contents_1_picture_id")
+ expect(assigns(:form_field_id)).to eq("element_1_ingredient_1_picture_id")
expect(assigns(:picture).id).to eq(picture.id)
end
end
diff --git a/spec/controllers/alchemy/api/contents_controller_spec.rb b/spec/controllers/alchemy/api/contents_controller_spec.rb
deleted file mode 100644
index d4fba343aa..0000000000
--- a/spec/controllers/alchemy/api/contents_controller_spec.rb
+++ /dev/null
@@ -1,143 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-module Alchemy
- describe Api::ContentsController do
- routes { Alchemy::Engine.routes }
-
- describe "#index" do
- let!(:page) { create(:alchemy_page) }
- let!(:element) { create(:alchemy_element, page: page) }
- let!(:content) { create(:alchemy_content, element: element) }
-
- it "returns all public contents as json objects" do
- get :index, params: {format: :json}
-
- expect(response.status).to eq(200)
- expect(response.media_type).to eq("application/json")
-
- result = JSON.parse(response.body)
-
- expect(result).to have_key("contents")
- expect(result["contents"].size).to eq(Alchemy::Content.count)
- end
-
- context "with element_id" do
- let!(:other_element) { create(:alchemy_element, page: page) }
- let!(:other_content) { create(:alchemy_content, element: other_element) }
-
- it "returns only contents from this element" do
- get :index, params: {element_id: other_element.id, format: :json}
-
- expect(response.status).to eq(200)
- expect(response.media_type).to eq("application/json")
-
- result = JSON.parse(response.body)
-
- expect(result).to have_key("contents")
- expect(result["contents"].size).to eq(1)
- expect(result["contents"][0]["element_id"]).to eq(other_element.id)
- end
- end
-
- context "with empty element_id" do
- it "returns all contents" do
- get :index, params: {element_id: element.id, format: :json}
-
- expect(response.status).to eq(200)
- expect(response.media_type).to eq("application/json")
-
- result = JSON.parse(response.body)
-
- expect(result).to have_key("contents")
- expect(result["contents"].size).to eq(Alchemy::Content.count)
- end
- end
-
- context "as author" do
- before do
- authorize_user(build(:alchemy_dummy_user, :as_author))
- end
-
- it "returns all contents" do
- get :index, params: {format: :json}
-
- expect(response.status).to eq(200)
- expect(response.media_type).to eq("application/json")
-
- result = JSON.parse(response.body)
-
- expect(result).to have_key("contents")
- expect(result["contents"].size).to eq(Alchemy::Content.count)
- end
- end
- end
-
- describe "#show" do
- context "with no other params given" do
- let(:page) { create(:alchemy_page) }
- let(:element) { create(:alchemy_element, page: page) }
- let(:content) { create(:alchemy_content, element: element) }
-
- it "returns content as json" do
- get :show, params: {id: content.id, format: :json}
-
- expect(response.status).to eq(200)
- expect(response.media_type).to eq("application/json")
-
- result = JSON.parse(response.body)
-
- expect(result["id"]).to eq(content.id)
- end
-
- context "requesting an restricted content" do
- let(:page) { create(:alchemy_page, restricted: true) }
-
- it "responds with 403" do
- get :show, params: {id: content.id, format: :json}
-
- expect(response.media_type).to eq("application/json")
- expect(response.status).to eq(403)
-
- result = JSON.parse(response.body)
-
- expect(result).to have_key("error")
- expect(result["error"]).to eq("Not authorized")
- end
- end
- end
-
- context "with element_id and name params given" do
- let!(:page) { create(:alchemy_page) }
- let!(:element) { create(:alchemy_element, page: page) }
- let!(:content) { create(:alchemy_content, element: element) }
-
- it "returns the named content from element with given id." do
- get :show, params: {element_id: element.id, name: content.name, format: :json}
-
- expect(response.status).to eq(200)
- expect(response.media_type).to eq("application/json")
-
- result = JSON.parse(response.body)
-
- expect(result["id"]).to eq(content.id)
- end
- end
-
- context "with empty element_id or name param" do
- it "returns 404 error." do
- get :show, params: {element_id: "", name: "", format: :json}
-
- expect(response.status).to eq(404)
- expect(response.media_type).to eq("application/json")
-
- result = JSON.parse(response.body)
-
- expect(result).to have_key("error")
- expect(result["error"]).to eq("Record not found")
- end
- end
- end
- end
-end
diff --git a/spec/controllers/alchemy/pages_controller_spec.rb b/spec/controllers/alchemy/pages_controller_spec.rb
index 14bbe4210b..993bc68578 100644
--- a/spec/controllers/alchemy/pages_controller_spec.rb
+++ b/spec/controllers/alchemy/pages_controller_spec.rb
@@ -178,7 +178,7 @@ module Alchemy
before do
allow(Alchemy.user_class).to receive(:admins).and_return(OpenStruct.new(count: 1))
- product.elements.find_by_name("article").contents.essence_texts.first.essence.update_column(:body, "screwdriver")
+ product.elements.find_by_name("article").ingredients.texts.first.update_column(:value, "screwdriver")
end
context "with correct levelnames in params" do
@@ -236,8 +236,8 @@ module Alchemy
let!(:english_page) { create(:alchemy_page, :public, language: default_language, name: "same-name") }
before do
- # Set a text in an essence rendered on the page so we can match against that
- klingon_page.essence_texts.first.update_column(:body, "klingon page")
+ # Set a text in an ingredient rendered on the page so we can match against that
+ klingon_page.ingredients.texts.first.update_column(:value, "klingon page")
end
it "renders the page related to its language" do
diff --git a/spec/decorators/alchemy/content_editor_spec.rb b/spec/decorators/alchemy/content_editor_spec.rb
deleted file mode 100644
index c177fd9429..0000000000
--- a/spec/decorators/alchemy/content_editor_spec.rb
+++ /dev/null
@@ -1,199 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-RSpec.describe Alchemy::ContentEditor do
- let(:essence) { Alchemy::EssenceText.new }
- let(:content) { Alchemy::Content.new(id: 1, essence: essence) }
- let(:content_editor) { described_class.new(content) }
-
- describe "#content" do
- it "returns content object" do
- expect(content_editor.content).to eq(content)
- end
- end
-
- describe "#css_classes" do
- subject { content_editor.css_classes }
-
- it "includes content_editor class" do
- is_expected.to include("content_editor")
- end
-
- it "includes essence partial class" do
- is_expected.to include(content_editor.essence_partial_name)
- end
-
- context "when deprecated" do
- before do
- expect(content).to receive(:deprecated?) { true }
- end
-
- it "includes deprecated" do
- is_expected.to include("deprecated")
- end
- end
- end
-
- describe "#data_attributes" do
- it "includes content_id" do
- expect(content_editor.data_attributes[:content_id]).to eq(content_editor.id)
- end
-
- it "includes content_name" do
- expect(content_editor.data_attributes[:content_name]).to eq(content_editor.name)
- end
- end
-
- describe "#to_partial_path" do
- subject { content_editor.to_partial_path }
-
- it "returns the editor partial path" do
- is_expected.to eq("alchemy/essences/essence_text_editor")
- end
- end
-
- describe "#form_field_name" do
- it "returns a name value for form fields with ingredient as default" do
- expect(content_editor.form_field_name).to eq("contents[1][ingredient]")
- end
-
- context "with a essence column given" do
- it "returns a name value for form fields for that column" do
- expect(content_editor.form_field_name(:link_title)).to eq("contents[1][link_title]")
- end
- end
- end
-
- describe "#form_field_id" do
- it "returns a id value for form fields with ingredient as default" do
- expect(content_editor.form_field_id).to eq("contents_1_ingredient")
- end
-
- context "with a essence column given" do
- it "returns a id value for form fields for that column" do
- expect(content_editor.form_field_id(:link_title)).to eq("contents_1_link_title")
- end
- end
- end
-
- describe "#respond_to?(:to_model)" do
- subject { content_editor.respond_to?(:to_model) }
-
- it { is_expected.to be(false) }
- end
-
- describe "#has_warnings?" do
- subject { content_editor.has_warnings? }
-
- context "when content is not deprecated" do
- let(:content) { build(:alchemy_content) }
-
- it { is_expected.to be(false) }
- end
-
- context "when content is deprecated" do
- let(:content) do
- mock_model("Content", definition: { deprecated: true }, deprecated?: true)
- end
-
- it { is_expected.to be(true) }
- end
-
- context "when content is missing its definition" do
- let(:content) do
- mock_model("Content", definition: {})
- end
-
- it { is_expected.to be(true) }
- end
- end
-
- describe "#warnings" do
- subject { content_editor.warnings }
-
- context "when content has no warnings" do
- let(:content) { build(:alchemy_content) }
-
- it { is_expected.to be_nil }
- end
-
- context "when content is missing its definition" do
- let(:content) do
- mock_model("Content", name: "foo", definition: {})
- end
-
- it { is_expected.to eq Alchemy.t(:content_definition_missing) }
-
- it "logs a warning" do
- expect(Alchemy::Logger).to receive(:warn)
- subject
- end
- end
-
- context "when content is deprecated" do
- let(:content) do
- mock_model("Content",
- name: "foo",
- definition: { "name" => "foo", "deprecated" => "Deprecated" },
- deprecated?: true)
- end
-
- it "returns a deprecation notice" do
- is_expected.to eq("Deprecated")
- end
- end
- end
-
- describe "#deprecation_notice" do
- subject { content_editor.deprecation_notice }
-
- context "when content is not deprecated" do
- let(:content) { build(:alchemy_content) }
-
- it { is_expected.to be_nil }
- end
-
- context "when content is deprecated" do
- let(:element) { build(:alchemy_element, name: "all_you_can_eat") }
- let(:content) { build(:alchemy_content, name: "essence_html", element: element) }
-
- context "with custom content translation" do
- it { is_expected.to eq("Old content is deprecated") }
- end
-
- context "without custom content translation" do
- let(:content) { build(:alchemy_content, name: "old_too", element: element) }
-
- before do
- allow(content).to receive(:definition) do
- {
- "name" => "old_too",
- "deprecated" => true,
- }
- end
- end
-
- it do
- is_expected.to eq(
- "WARNING! This content is deprecated and will be removed soon. " \
- "Please do not use it anymore."
- )
- end
- end
-
- context "with String as deprecation" do
- before do
- allow(content).to receive(:definition) do
- {
- "name" => "old",
- "deprecated" => "Foo baz widget",
- }
- end
- end
-
- it { is_expected.to eq("Foo baz widget") }
- end
- end
- end
-end
diff --git a/spec/decorators/alchemy/element_editor_spec.rb b/spec/decorators/alchemy/element_editor_spec.rb
index 49e0290cdf..e58d6c8ac2 100644
--- a/spec/decorators/alchemy/element_editor_spec.rb
+++ b/spec/decorators/alchemy/element_editor_spec.rb
@@ -12,50 +12,12 @@
end
end
- describe "#contents" do
- let(:element) { create(:alchemy_element, :with_contents, name: "headline") }
-
- subject(:contents) { element_editor.contents }
-
- it "returns a ContentEditor instance for each content defined" do
- aggregate_failures do
- contents.each do |content|
- expect(content).to be_an(Alchemy::ContentEditor)
- end
- end
- end
-
- context "with a content defined but not existing yet" do
- before do
- expect(element).to receive(:definition).at_least(:once) do
- {
- name: "headline",
- contents: [
- {
- name: "headline",
- type: "EssenceText",
- },
- {
- name: "foo",
- type: "EssenceText",
- },
- ],
- }.with_indifferent_access
- end
- end
-
- it "creates the missing content" do
- expect { subject }.to change { element.contents.count }.by(1)
- end
- end
- end
-
describe "#ingredients" do
let(:element) { create(:alchemy_element, :with_ingredients) }
subject(:ingredients) { element_editor.ingredients }
- it "returns a ContentEditor instance for each ingredient defined" do
+ it "returns a IngredientEditor instance for each ingredient defined" do
aggregate_failures do
ingredients.each do |ingredient|
expect(ingredient).to be_an(Alchemy::IngredientEditor)
@@ -141,20 +103,20 @@
it { is_expected.to include("not-taggable") }
end
- context "with element having content_definitions" do
+ context "with element having ingredient_definitions" do
before do
- allow(element).to receive(:content_definitions) { [1] }
+ allow(element).to receive(:ingredient_definitions) { [1] }
end
- it { is_expected.to include("with-contents") }
+ it { is_expected.to include("with-ingredients") }
end
- context "with element not having content_definitions" do
+ context "with element not having ingredient_definitions" do
before do
- allow(element).to receive(:content_definitions) { [] }
+ allow(element).to receive(:ingredient_definitions) { [] }
end
- it { is_expected.to include("without-contents") }
+ it { is_expected.to include("without-ingredients") }
end
context "with element having nestable_elements" do
@@ -194,14 +156,14 @@
context "for expanded element" do
before { allow(element).to receive(:folded?) { false } }
- context "and element having contents defined" do
- before { allow(element).to receive(:content_definitions) { [1] } }
+ context "and element having ingredients defined" do
+ before { allow(element).to receive(:ingredient_definitions) { [1] } }
it { is_expected.to eq(true) }
end
- context "and element having no contents defined" do
- before { allow(element).to receive(:content_definitions) { [] } }
+ context "and element having no ingredients defined" do
+ before { allow(element).to receive(:ingredient_definitions) { [] } }
context "and element beeing taggable" do
before { allow(element).to receive(:taggable?) { true } }
@@ -214,18 +176,6 @@
it { is_expected.to eq(false) }
end
-
- context "but element has ingredients defined" do
- before {
- expect(element).to receive(:ingredient_definitions) {
- [{
- role: "headline", type: "Headline",
- }]
- }
- }
-
- it { is_expected.to eq(true) }
- end
end
end
end
diff --git a/spec/decorators/alchemy/ingredient_editor_spec.rb b/spec/decorators/alchemy/ingredient_editor_spec.rb
index f260319abe..52c246f451 100644
--- a/spec/decorators/alchemy/ingredient_editor_spec.rb
+++ b/spec/decorators/alchemy/ingredient_editor_spec.rb
@@ -3,7 +3,7 @@
require "rails_helper"
RSpec.describe Alchemy::IngredientEditor do
- let(:element) { build(:alchemy_element, name: "element_with_ingredients") }
+ let(:element) { build(:alchemy_element, name: "article") }
let(:ingredient) { Alchemy::Ingredients::Text.new(role: "headline", element: element) }
let(:ingredient_editor) { described_class.new(ingredient) }
@@ -16,11 +16,11 @@
describe "#css_classes" do
subject { ingredient_editor.css_classes }
- it "includes ingredient_editor class" do
+ it "includes ingredient-editor class" do
is_expected.to include("ingredient-editor")
end
- it "includes essence partial class" do
+ it "includes ingredient partial name class" do
is_expected.to include(ingredient.partial_name)
end
@@ -99,12 +99,12 @@
describe "#form_field_name" do
it "returns a name for form fields with value as default" do
- expect(ingredient_editor.form_field_name).to eq("element[ingredients_attributes][0][value]")
+ expect(ingredient_editor.form_field_name).to eq("element[ingredients_attributes][1][value]")
end
context "with a value given" do
it "returns a name for form fields for that column" do
- expect(ingredient_editor.form_field_name(:link_title)).to eq("element[ingredients_attributes][0][link_title]")
+ expect(ingredient_editor.form_field_name(:link_title)).to eq("element[ingredients_attributes][1][link_title]")
end
end
end
@@ -224,14 +224,14 @@
it do
is_expected.to eq(
- "WARNING! This content is deprecated and will be removed soon. " \
+ "WARNING! This field is deprecated and will be removed soon. " \
"Please do not use it anymore."
)
end
end
context "with custom ingredient translation" do
- let(:element) { build(:alchemy_element, name: "all_you_can_eat_ingredients") }
+ let(:element) { build(:alchemy_element, name: "all_you_can_eat") }
let(:ingredient) do
Alchemy::Ingredients::Html.new(
diff --git a/spec/dummy/app/assets/stylesheets/alchemy/elements/_all_you_can_eat.scss b/spec/dummy/app/assets/stylesheets/alchemy/elements/_all_you_can_eat.scss
index e784618297..5203613a55 100644
--- a/spec/dummy/app/assets/stylesheets/alchemy/elements/_all_you_can_eat.scss
+++ b/spec/dummy/app/assets/stylesheets/alchemy/elements/_all_you_can_eat.scss
@@ -1,5 +1,5 @@
.all_you_can_eat {
- .essence_picture {
+ .ingredient-editor.picture {
max-width: 50%;
img {
diff --git a/spec/dummy/app/models/dummy_model.rb b/spec/dummy/app/models/dummy_model.rb
deleted file mode 100644
index 7a369c9ff7..0000000000
--- a/spec/dummy/app/models/dummy_model.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: true
-
-class DummyModel < ActiveRecord::Base
- acts_as_essence ingredient_column: "data"
-end
diff --git a/spec/dummy/app/views/alchemy/elements/_all_you_can_eat.html.erb b/spec/dummy/app/views/alchemy/elements/_all_you_can_eat.html.erb
index 6ee5c33fe0..0e2c88462a 100644
--- a/spec/dummy/app/views/alchemy/elements/_all_you_can_eat.html.erb
+++ b/spec/dummy/app/views/alchemy/elements/_all_you_can_eat.html.erb
@@ -1,31 +1,46 @@
<%- cache(all_you_can_eat) do -%>
<%= element_view_for(all_you_can_eat) do |el| -%>
-
- <%= el.render :essence_text %>
+
+ <%= el.render(:headline) %>
-
- <%= el.render :essence_picture %>
+
+ <%= el.render(:text) %>
-
- <%= el.render :essence_richtext %>
+
+ <%= el.render(:picture) %>
-
- <%= el.render :essence_select %>
+
+ <%= el.render(:richtext) %>
-
- <%= el.render :essence_boolean %>
+
+ <%= el.render(:select) %>
-
- <%= el.render :essence_date %>
+
+ <%= el.render(:boolean) %>
-
- <%= el.render :essence_file %>
+
+ <%= el.render(:datetime) %>
-
- <%= el.render :essence_html %>
+
+ <%= el.render(:file) %>
-
- <%= el.render :essence_link %>
+
+ <%= el.render(:html) %>
+
+
+ <%= el.render(:link) %>
+
+
+ <%= el.render(:node) %>
+
+
+ <%= el.render(:audio) %>
+
+
+ <%= el.render(:video) %>
+
+
+ <%= el.render(:page) %>
<%- end -%>
<%- end -%>
diff --git a/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_ingredients.html.erb b/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_ingredients.html.erb
deleted file mode 100644
index 23bb9b9070..0000000000
--- a/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_ingredients.html.erb
+++ /dev/null
@@ -1,46 +0,0 @@
-<%- cache(all_you_can_eat_ingredients) do -%>
- <%= element_view_for(all_you_can_eat_ingredients) do |el| -%>
-
- <%= el.render(:headline) %>
-
-
- <%= el.render(:text) %>
-
-
- <%= el.render(:picture) %>
-
-
- <%= el.render(:richtext) %>
-
-
- <%= el.render(:select) %>
-
-
- <%= el.render(:boolean) %>
-
-
- <%= el.render(:datetime) %>
-
-
- <%= el.render(:file) %>
-
-
- <%= el.render(:html) %>
-
-
- <%= el.render(:link) %>
-
-
- <%= el.render(:node) %>
-
-
- <%= el.render(:audio) %>
-
-
- <%= el.render(:video) %>
-
-
- <%= el.render(:page) %>
-
- <%- end -%>
-<%- end -%>
diff --git a/spec/dummy/app/views/alchemy/elements/_element_with_ingredients.html.erb b/spec/dummy/app/views/alchemy/elements/_element_with_ingredients.html.erb
deleted file mode 100644
index d1e75a5979..0000000000
--- a/spec/dummy/app/views/alchemy/elements/_element_with_ingredients.html.erb
+++ /dev/null
@@ -1,10 +0,0 @@
-<%- cache(element_with_ingredients) do -%>
- <%= element_view_for(element_with_ingredients) do |el| -%>
-
- <%= el.render(:headline) %>
-
-
- <%= el.render(:text) %>
-
- <%- end -%>
-<%- end -%>
diff --git a/spec/dummy/config/alchemy/elements.yml b/spec/dummy/config/alchemy/elements.yml
index e8ec8ddca6..9b5d2eaab2 100644
--- a/spec/dummy/config/alchemy/elements.yml
+++ b/spec/dummy/config/alchemy/elements.yml
@@ -1,128 +1,86 @@
- name: header
unique: true
- contents:
- - name: image
- type: EssencePicture
+ ingredients:
+ - role: image
+ type: Picture
- name: headline
- contents:
- - name: headline
- type: EssenceHeadline
+ ingredients:
+ - role: headline
+ type: Headline
- name: article
taggable: true
- contents:
- - name: intro
- type: EssenceText
- - name: headline
- type: EssenceText
+ ingredients:
+ - role: intro
+ type: Text
settings:
linkable: true
- - name: image
- type: EssencePicture
+ - role: headline
+ type: Headline
+ settings:
+ anchor: from_value
+ - role: image
+ type: Picture
settings:
size: 450x300
crop: true
- - name: text
- type: EssenceRichtext
+ - role: text
+ type: Richtext
- name: text
- contents:
- - name: text
- type: EssenceRichtext
+ ingredients:
+ - role: text
+ type: Richtext
settings:
sanitizer:
attributes: [href, target]
tags: [p, ol, ul, ul, li, em, strong]
- name: search
- contents: []
+ ingredients: []
- name: news
- contents:
- - name: date
- type: EssenceDate
- - name: news_headline
- type: EssenceText
- - name: body
- type: EssenceRichtext
+ ingredients:
+ - role: date
+ type: Datetime
+ - role: news_headline
+ type: Text
+ - role: body
+ type: Richtext
- name: download
- contents:
- - name: file
- type: EssenceFile
+ ingredients:
+ - role: file
+ type: File
- name: bild
- contents:
- - name: image
- type: EssencePicture
+ ingredients:
+ - role: image
+ type: Picture
- name: contactform
unique: true
- contents:
- - name: mail_from
- type: EssenceText
+ ingredients:
+ - role: mail_from
+ type: Text
validate:
- presence
- - name: mail_to
- type: EssenceText
+ - role: mail_to
+ type: Text
validate:
- presence
- - name: subject
- type: EssenceText
+ - role: subject
+ type: Text
as_element_title: true
validate:
- presence
- - name: success_page
- type: EssencePage
+ - role: success_page
+ type: Page
validate:
- presence
- name: all_you_can_eat
- hint: true
- taggable: true
- contents:
- - name: essence_text
- type: EssenceText
- hint: true
- - name: essence_picture
- type: EssencePicture
- hint: true
- settings:
- size: 1200x480
- crop: true
- - name: essence_richtext
- type: EssenceRichtext
- hint: true
- - name: essence_select
- type: EssenceSelect
- hint: true
- settings:
- select_values: [A, B, C]
- - name: essence_boolean
- type: EssenceBoolean
- hint: true
- - name: essence_date
- type: EssenceDate
- hint: true
- - name: essence_audio
- type: EssenceAudio
- hint: true
- - name: essence_file
- type: EssenceFile
- hint: true
- - name: essence_video
- type: EssenceVideo
- hint: true
- - name: essence_html
- type: EssenceHtml
- hint: true
- deprecated: true
- - name: essence_link
- type: EssenceLink
- hint: true
-
-- name: all_you_can_eat_ingredients
hint: true
taggable: true
ingredients:
@@ -189,17 +147,17 @@
hint: true
- name: <%= 'erb_' + 'element' %>
- contents:
- - name: text
- type: EssenceRichtext
+ ingredients:
+ - role: text
+ type: Richtext
- name: slide
compact: true
- contents:
- - name: picture
- type: EssencePicture
- - name: caption
- type: EssenceText
+ ingredients:
+ - role: picture
+ type: Picture
+ - role: caption
+ type: Text
as_element_title: true
- name: slider
@@ -214,9 +172,9 @@
- name: gallery_picture
compact: true
- contents:
- - name: picture
- type: EssencePicture
+ ingredients:
+ - role: picture
+ type: Picture
settings:
size: 160x120
crop: true
@@ -224,9 +182,9 @@
- name: right_column
fixed: true
unique: true
- contents:
- - name: title
- type: EssenceText
+ ingredients:
+ - role: title
+ type: Text
nestable_elements: [search, text]
- name: left_column
@@ -240,29 +198,17 @@
nestable_elements: [text]
- name: menu
- contents:
- - name: menu
- type: EssenceNode
+ ingredients:
+ - role: menu
+ type: Node
- name: old
deprecated: true
- contents:
- - name: title
- type: EssenceText
- - name: text
- type: EssenceRichtext
-
-- name: element_with_ingredients
ingredients:
- - role: headline
+ - role: title
type: Text
- default: Hello World
- settings:
- anchor: from_value
- linkable: true
- role: text
type: Richtext
- default: :lorem_ipsum
- name: element_with_ingredient_groups
ingredients:
@@ -280,20 +226,3 @@
- role: key_words
type: Text
group: details
-
-- name: element_with_content_groups
- contents:
- - name: title
- type: EssenceText
- - name: description
- type: EssenceRichtext
- group: details
- - name: width
- type: EssenceText
- group: size
- - name: height
- type: EssenceText
- group: size
- - name: key_words
- type: EssenceText
- group: details
diff --git a/spec/dummy/config/alchemy/page_layouts.yml b/spec/dummy/config/alchemy/page_layouts.yml
index bebd60e961..8ec281e991 100644
--- a/spec/dummy/config/alchemy/page_layouts.yml
+++ b/spec/dummy/config/alchemy/page_layouts.yml
@@ -1,9 +1,9 @@
- name: index
unique: true
elements:
- - all_you_can_eat_ingredients
+ - all_you_can_eat
autogenerate:
- - all_you_can_eat_ingredients
+ - all_you_can_eat
- name: readonly
fixed_attributes:
@@ -32,10 +32,8 @@
right_column,
left_column,
old,
- all_you_can_eat_ingredients,
- element_with_ingredients,
- element_with_ingredient_groups,
- element_with_content_groups
+ article,
+ element_with_ingredient_groups
]
autogenerate: [all_you_can_eat, right_column, left_column]
diff --git a/spec/dummy/config/locales/alchemy.de.yml b/spec/dummy/config/locales/alchemy.de.yml
index 65331fa8e2..9e709137a7 100644
--- a/spec/dummy/config/locales/alchemy.de.yml
+++ b/spec/dummy/config/locales/alchemy.de.yml
@@ -1,24 +1,24 @@
de:
alchemy:
- content_names:
- essence_boolean: EssenceBoolean
- essence_date: EssenceDate
- essence_file: EssenceFile
- essence_html: EssenceHtml
- essence_link: EssenceLink
- essence_picture: EssencePicture
- essence_richtext: EssenceRichtext
- essence_select: EssenceSelect
- essence_text: EssenceText
+ ingredient_roles:
+ boolean: Boolean
+ datetime: Date/Time
+ file: File
+ html: HTML
+ link: Link
+ picture: Picture
+ richtext: Richtext
+ select: Select
+ text: Text
element_hints:
- all_you_can_eat: Dieses Element zeigt alle Inhaltstypen (Essenzen) und Funktionen eines Elements mit denen Alchemy ausgeliefert wird.
- content_hints:
- essence_boolean: Dieser Inhaltstyp (Essenz) stellt einenen simplen ja/nein Wert da
- essence_date: Dieser Inhaltstyp (Essenz) stellt einen Datumswert dar
- essence_file: Dieser Inhaltstyp (Essenz) stellt eine herunterladbare Datei dar
- essence_html: Dieser Inhaltstyp (Essenz) stellt reine HTML Ausgabe dar
- essence_link: Dieser Inhaltstyp (Essenz) stellt einen Link dar
- essence_picture: Dieser Inhaltstyp (Essenz) stellt ein Bild dar
- essence_richtext: Dieser Inhaltstyp (Essenz) stellt formatierbaren Text dar
- essence_select: Dieser Inhaltstyp (Essenz) stellt Werte dar aus denen der Redakteur wählen kann
- essence_text: Dieser Inhaltstyp (Essenz) stellt eine einfache Zeile Text dar
+ all_you_can_eat: Dieses Element zeigt alle Inhaltstypen und Funktionen eines Elements mit denen Alchemy ausgeliefert wird.
+ ingredient_hints:
+ boolean: Dieser Inhaltstyp stellt einenen simplen ja/nein Wert da
+ datetime: Dieser Inhaltstyp stellt einen Datums- oder Zeitwert dar
+ file: Dieser Inhaltstyp stellt eine herunterladbare Datei dar
+ html: Dieser Inhaltstyp stellt reine HTML Ausgabe dar
+ link: Dieser Inhaltstyp stellt einen Link dar
+ picture: Dieser Inhaltstyp stellt ein Bild dar
+ richtext: Dieser Inhaltstyp stellt formatierbaren Text dar
+ select: Dieser Inhaltstyp stellt Werte dar aus denen der Redakteur wählen kann
+ text: Dieser Inhaltstyp stellt eine einfache Zeile Text dar
diff --git a/spec/dummy/config/locales/alchemy.en.yml b/spec/dummy/config/locales/alchemy.en.yml
index 85c93e75de..825a9b6745 100644
--- a/spec/dummy/config/locales/alchemy.en.yml
+++ b/spec/dummy/config/locales/alchemy.en.yml
@@ -8,40 +8,36 @@ en:
name: Location
element_names:
gallery_picture: Gallery picture
- content_names:
- essence_boolean: EssenceBoolean
- essence_date: EssenceDate
- essence_file: EssenceFile
- essence_html: EssenceHtml
- essence_link: EssenceLink
- essence_picture: EssencePicture
- essence_richtext: EssenceRichtext
- essence_select: EssenceSelect
- essence_text: EssenceText
+ ingredient_roles:
+ boolean: Boolean
+ datetime: Date/Time
+ file: File
+ html: HTML
+ link: Link
+ picture: Picture
+ richtext: Richtext
+ select: Select
+ text: Text
element_hints:
- all_you_can_eat: This element shows all content types (Essences) and settings of an Element Alchemy comes with in a default installation.
- content_hints:
- essence_boolean: This content type (Essence) represents a simple true/false value
- essence_date: This content type (Essence) represents a date value
- essence_file: This content type (Essence) represents a downloadable file
- essence_html: This content type (Essence) represents raw HTML output
- essence_link: This content type (Essence) represents a link
- essence_picture: This content type (Essence) represents a picture
- essence_richtext: This content type (Essence) represents richtext
- essence_select: This content type (Essence) represents values the editor can choose from
- essence_text: This content type (Essence) represents a simple line of text
- default_content_texts:
- welcome: Welcome to my site
+ all_you_can_eat: This element shows all ingredient types and settings of an Element Alchemy comes with in a default installation.
+ ingredient_hints:
+ boolean: This ingredient type represents a simple true/false value
+ datetime: This ingredient type represents a date or time value
+ file: This ingredient type represents a downloadable file
+ html: This ingredient type represents raw HTML output
+ link: This ingredient type represents a link
+ picture: This ingredient type represents a picture
+ richtext: This ingredient type represents richtext
+ select: This ingredient type represents values the editor can choose from
+ text: This ingredient type represents a simple line of text
default_ingredient_texts:
lorem_ipsum: Dapibus nostra massa phasellus viverra rhoncus fringilla
+ welcome: Welcome to my site
resource_help_texts:
party:
name: Party
- content_deprecation_notices:
- all_you_can_eat:
- essence_html: Old content is deprecated
ingredient_deprecation_notices:
- all_you_can_eat_ingredients:
+ all_you_can_eat:
html: Old ingredient is deprecated
element_deprecation_notices:
old: Old element is deprecated
@@ -53,13 +49,12 @@ en:
fields:
select:
taken: "Please select something else"
- all_you_can_eat_ingredients:
+ all_you_can_eat:
headline:
blank: Please enter a headline for all you can eat
page_hints:
everything: This page is for everything.
-
activemodel:
models:
foo_preview_source: Foo Preview
diff --git a/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb b/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb
deleted file mode 100644
index 0d870e645d..0000000000
--- a/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class CreateDummyModel < ActiveRecord::Migration[4.2]
- def change
- create_table :dummy_models do |t|
- t.string :data
- end
- end
-end
diff --git a/spec/dummy/db/migrate/20200226213334_alchemy_four_point_four.rb b/spec/dummy/db/migrate/20200226213334_alchemy_four_point_four.rb
deleted file mode 120000
index 7c5bd382df..0000000000
--- a/spec/dummy/db/migrate/20200226213334_alchemy_four_point_four.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200226213334_alchemy_four_point_four.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20200423073425_create_alchemy_essence_nodes.rb b/spec/dummy/db/migrate/20200423073425_create_alchemy_essence_nodes.rb
deleted file mode 120000
index 7c19075432..0000000000
--- a/spec/dummy/db/migrate/20200423073425_create_alchemy_essence_nodes.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200423073425_create_alchemy_essence_nodes.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20200504210159_remove_site_id_from_nodes.rb b/spec/dummy/db/migrate/20200504210159_remove_site_id_from_nodes.rb
deleted file mode 120000
index 6c80fe7846..0000000000
--- a/spec/dummy/db/migrate/20200504210159_remove_site_id_from_nodes.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200504210159_remove_site_id_from_nodes.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb b/spec/dummy/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb
deleted file mode 120000
index b13520df09..0000000000
--- a/spec/dummy/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb b/spec/dummy/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb
deleted file mode 120000
index 11efc9ef63..0000000000
--- a/spec/dummy/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20200514091507_make_page_layoutpage_null_false.rb b/spec/dummy/db/migrate/20200514091507_make_page_layoutpage_null_false.rb
deleted file mode 120000
index 4d55e7a290..0000000000
--- a/spec/dummy/db/migrate/20200514091507_make_page_layoutpage_null_false.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200514091507_make_page_layoutpage_null_false.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb b/spec/dummy/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb
deleted file mode 120000
index 3e5342b228..0000000000
--- a/spec/dummy/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb b/spec/dummy/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb
deleted file mode 120000
index 9e9ff2ed7c..0000000000
--- a/spec/dummy/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200617110713_create_alchemy_picture_thumbs.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20200907111332_remove_tri_state_booleans.rb b/spec/dummy/db/migrate/20200907111332_remove_tri_state_booleans.rb
deleted file mode 120000
index 063e53e65f..0000000000
--- a/spec/dummy/db/migrate/20200907111332_remove_tri_state_booleans.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20200907111332_remove_tri_state_booleans.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20201207131309_create_page_versions.rb b/spec/dummy/db/migrate/20201207131309_create_page_versions.rb
deleted file mode 120000
index 0377235c35..0000000000
--- a/spec/dummy/db/migrate/20201207131309_create_page_versions.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20201207131309_create_page_versions.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb b/spec/dummy/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb
deleted file mode 120000
index 0a3f03a90d..0000000000
--- a/spec/dummy/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb b/spec/dummy/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb
deleted file mode 120000
index 5945aff82e..0000000000
--- a/spec/dummy/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb b/spec/dummy/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb
deleted file mode 120000
index a6812a41e3..0000000000
--- a/spec/dummy/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20210406093436_add_alchemy_essence_headlines.rb b/spec/dummy/db/migrate/20210406093436_add_alchemy_essence_headlines.rb
deleted file mode 120000
index cd30968cd8..0000000000
--- a/spec/dummy/db/migrate/20210406093436_add_alchemy_essence_headlines.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20210406093436_add_alchemy_essence_headlines.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20210506135919_create_essence_audios.rb b/spec/dummy/db/migrate/20210506135919_create_essence_audios.rb
deleted file mode 120000
index adcf4f1412..0000000000
--- a/spec/dummy/db/migrate/20210506135919_create_essence_audios.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20210506135919_create_essence_audios.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20210506140258_create_essence_videos.rb b/spec/dummy/db/migrate/20210506140258_create_essence_videos.rb
deleted file mode 120000
index 3e82a38f4c..0000000000
--- a/spec/dummy/db/migrate/20210506140258_create_essence_videos.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20210506140258_create_essence_videos.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20210508091432_create_alchemy_ingredients.rb b/spec/dummy/db/migrate/20210508091432_create_alchemy_ingredients.rb
deleted file mode 120000
index e94fcb1c52..0000000000
--- a/spec/dummy/db/migrate/20210508091432_create_alchemy_ingredients.rb
+++ /dev/null
@@ -1 +0,0 @@
-../../../../db/migrate/20210508091432_create_alchemy_ingredients.rb
\ No newline at end of file
diff --git a/spec/dummy/db/migrate/20220831084620_add_playsinline_to_alchemy_essence_videos.alchemy.rb b/spec/dummy/db/migrate/20220831084620_add_playsinline_to_alchemy_essence_videos.alchemy.rb
deleted file mode 100644
index b7dc1075fc..0000000000
--- a/spec/dummy/db/migrate/20220831084620_add_playsinline_to_alchemy_essence_videos.alchemy.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-# This migration comes from alchemy (originally 20220622130905)
-class AddPlaysinlineToAlchemyEssenceVideos < ActiveRecord::Migration[6.0]
- def change
- return if column_exists?(:alchemy_essence_videos, :playsinline)
-
- add_column :alchemy_essence_videos, :playsinline, :boolean, default: false, null: false
- end
-end
diff --git a/spec/dummy/db/migrate/20191129235819_gutentag_tables.gutentag.rb b/spec/dummy/db/migrate/20230119091654_gutentag_tables.gutentag.rb
similarity index 78%
rename from spec/dummy/db/migrate/20191129235819_gutentag_tables.gutentag.rb
rename to spec/dummy/db/migrate/20230119091654_gutentag_tables.gutentag.rb
index 4dbea15c75..3b444996b8 100644
--- a/spec/dummy/db/migrate/20191129235819_gutentag_tables.gutentag.rb
+++ b/spec/dummy/db/migrate/20230119091654_gutentag_tables.gutentag.rb
@@ -1,13 +1,8 @@
# frozen_string_literal: true
-# This migration comes from gutentag (originally 1)
-superclass = ActiveRecord::VERSION::MAJOR < 5 ?
- ActiveRecord::Migration : ActiveRecord::Migration[4.2]
-class GutentagTables < superclass
+# This migration comes from gutentag (originally 1)
+class GutentagTables < ActiveRecord::Migration[4.2]
def up
- # inserted by Alchemy CMS upgrader
- return if table_exists?(:gutentag_taggings)
-
create_table :gutentag_taggings do |t|
t.integer :tag_id, :null => false
t.integer :taggable_id, :null => false
diff --git a/spec/dummy/db/migrate/20191129235820_gutentag_cache_counter.gutentag.rb b/spec/dummy/db/migrate/20230119091655_gutentag_cache_counter.gutentag.rb
similarity index 64%
rename from spec/dummy/db/migrate/20191129235820_gutentag_cache_counter.gutentag.rb
rename to spec/dummy/db/migrate/20230119091655_gutentag_cache_counter.gutentag.rb
index cc093b257f..c00edd42da 100644
--- a/spec/dummy/db/migrate/20191129235820_gutentag_cache_counter.gutentag.rb
+++ b/spec/dummy/db/migrate/20230119091655_gutentag_cache_counter.gutentag.rb
@@ -1,13 +1,8 @@
# frozen_string_literal: true
-# This migration comes from gutentag (originally 2)
-superclass = ActiveRecord::VERSION::MAJOR < 5 ?
- ActiveRecord::Migration : ActiveRecord::Migration[4.2]
-class GutentagCacheCounter < superclass
+# This migration comes from gutentag (originally 2)
+class GutentagCacheCounter < ActiveRecord::Migration[4.2]
def up
- # inserted by Alchemy CMS upgrader
- return if column_exists?(:gutentag_tags, :taggings_count)
-
add_column :gutentag_tags, :taggings_count, :integer, :default => 0
add_index :gutentag_tags, :taggings_count
diff --git a/spec/dummy/db/migrate/20191129235821_no_null_counters.gutentag.rb b/spec/dummy/db/migrate/20230119091656_no_null_counters.gutentag.rb
similarity index 70%
rename from spec/dummy/db/migrate/20191129235821_no_null_counters.gutentag.rb
rename to spec/dummy/db/migrate/20230119091656_no_null_counters.gutentag.rb
index 8503167f75..17939cae84 100644
--- a/spec/dummy/db/migrate/20191129235821_no_null_counters.gutentag.rb
+++ b/spec/dummy/db/migrate/20230119091656_no_null_counters.gutentag.rb
@@ -1,9 +1,7 @@
# frozen_string_literal: true
-# This migration comes from gutentag (originally 3)
-superclass = ActiveRecord::VERSION::MAJOR < 5 ?
- ActiveRecord::Migration : ActiveRecord::Migration[4.2]
-class NoNullCounters < superclass
+# This migration comes from gutentag (originally 3)
+class NoNullCounters < ActiveRecord::Migration[4.2]
def up
change_column :gutentag_tags, :taggings_count, :integer,
:default => 0,
diff --git a/spec/dummy/db/migrate/20230119091717_alchemy_four_point_four.alchemy.rb b/spec/dummy/db/migrate/20230119091717_alchemy_four_point_four.alchemy.rb
new file mode 100644
index 0000000000..1c76b95a65
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091717_alchemy_four_point_four.alchemy.rb
@@ -0,0 +1,201 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20200226213334)
+class AlchemyFourPointFour < ActiveRecord::Migration[6.0]
+ def up
+ unless table_exists?("alchemy_attachments")
+ create_table "alchemy_attachments" do |t|
+ t.string "name"
+ t.string "file_name"
+ t.string "file_mime_type"
+ t.integer "file_size"
+ t.references "creator"
+ t.references "updater"
+ t.timestamps
+ t.string "file_uid"
+ t.index ["file_uid"], name: "index_alchemy_attachments_on_file_uid"
+ end
+ end
+
+ unless table_exists?("alchemy_elements")
+ create_table "alchemy_elements" do |t|
+ t.string "name"
+ t.integer "position"
+ t.references "page", null: false, index: false
+ t.boolean "public", default: true
+ t.boolean "folded", default: false
+ t.boolean "unique", default: false
+ t.timestamps
+ t.references "creator"
+ t.references "updater"
+ t.references "parent_element", index: false
+ t.boolean "fixed", default: false, null: false
+ t.index ["fixed"], name: "index_alchemy_elements_on_fixed"
+ t.index ["page_id", "parent_element_id"], name: "index_alchemy_elements_on_page_id_and_parent_element_id"
+ t.index ["page_id", "position"], name: "index_elements_on_page_id_and_position"
+ end
+ end
+
+ unless table_exists?("alchemy_elements_alchemy_pages")
+ create_table "alchemy_elements_alchemy_pages", id: false do |t|
+ t.references "element"
+ t.references "page"
+ end
+ end
+
+ unless table_exists?("alchemy_folded_pages")
+ create_table "alchemy_folded_pages" do |t|
+ t.references "page", null: false, index: false
+ t.references "user", null: false, index: false
+ t.boolean "folded", default: false
+ t.index ["page_id", "user_id"], name: "index_alchemy_folded_pages_on_page_id_and_user_id", unique: true
+ end
+ end
+
+ unless table_exists?("alchemy_languages")
+ create_table "alchemy_languages" do |t|
+ t.string "name"
+ t.string "language_code"
+ t.string "frontpage_name"
+ t.string "page_layout", default: "intro"
+ t.boolean "public", default: false
+ t.timestamps
+ t.references "creator"
+ t.references "updater"
+ t.boolean "default", default: false
+ t.string "country_code", default: "", null: false
+ t.references "site", null: false
+ t.string "locale"
+ t.index ["language_code", "country_code"], name: "index_alchemy_languages_on_language_code_and_country_code"
+ t.index ["language_code"], name: "index_alchemy_languages_on_language_code"
+ end
+ end
+
+ unless table_exists?("alchemy_legacy_page_urls")
+ create_table "alchemy_legacy_page_urls" do |t|
+ t.string "urlname", null: false
+ t.references "page", null: false
+ t.timestamps
+ t.index ["urlname"], name: "index_alchemy_legacy_page_urls_on_urlname"
+ end
+ end
+
+ unless table_exists?("alchemy_nodes")
+ create_table "alchemy_nodes" do |t|
+ t.string "name"
+ t.string "title"
+ t.string "url"
+ t.boolean "nofollow", default: false, null: false
+ t.boolean "external", default: false, null: false
+ t.boolean "folded", default: false, null: false
+ t.references "parent"
+ t.integer "lft", null: false
+ t.integer "rgt", null: false
+ t.integer "depth", default: 0, null: false
+ t.references "page"
+ t.references "language", null: false
+ t.references "creator"
+ t.references "updater"
+ t.timestamps
+ t.references "site", null: false
+ t.index ["lft"], name: "index_alchemy_nodes_on_lft"
+ t.index ["rgt"], name: "index_alchemy_nodes_on_rgt"
+ end
+ end
+
+ unless table_exists?("alchemy_pages")
+ create_table "alchemy_pages" do |t|
+ t.string "name"
+ t.string "urlname"
+ t.string "title"
+ t.string "language_code"
+ t.boolean "language_root"
+ t.string "page_layout"
+ t.text "meta_keywords"
+ t.text "meta_description"
+ t.integer "lft"
+ t.integer "rgt"
+ t.references "parent", index: false
+ t.integer "depth"
+ t.boolean "visible", default: false
+ t.integer "locked_by"
+ t.boolean "restricted", default: false
+ t.boolean "robot_index", default: true
+ t.boolean "robot_follow", default: true
+ t.boolean "sitemap", default: true
+ t.boolean "layoutpage", default: false
+ t.timestamps
+ t.references "creator"
+ t.references "updater"
+ t.references "language"
+ t.datetime "published_at"
+ t.datetime "public_on"
+ t.datetime "public_until"
+ t.datetime "locked_at"
+ t.index ["locked_at", "locked_by"], name: "index_alchemy_pages_on_locked_at_and_locked_by"
+ t.index ["parent_id", "lft"], name: "index_pages_on_parent_id_and_lft"
+ t.index ["public_on", "public_until"], name: "index_alchemy_pages_on_public_on_and_public_until"
+ t.index ["rgt"], name: "index_alchemy_pages_on_rgt"
+ t.index ["urlname"], name: "index_pages_on_urlname"
+ end
+ end
+
+ unless table_exists?("alchemy_pictures")
+ create_table "alchemy_pictures" do |t|
+ t.string "name"
+ t.string "image_file_name"
+ t.integer "image_file_width"
+ t.integer "image_file_height"
+ t.timestamps
+ t.references "creator"
+ t.references "updater"
+ t.string "upload_hash"
+ t.string "image_file_uid"
+ t.integer "image_file_size"
+ t.string "image_file_format"
+ end
+ end
+
+ unless table_exists?("alchemy_sites")
+ create_table "alchemy_sites" do |t|
+ t.string "host"
+ t.string "name"
+ t.timestamps
+ t.boolean "public", default: false
+ t.text "aliases"
+ t.boolean "redirect_to_primary_host"
+ t.index ["host", "public"], name: "alchemy_sites_public_hosts_idx"
+ t.index ["host"], name: "index_alchemy_sites_on_host"
+ end
+ end
+
+ unless foreign_key_exists?("alchemy_elements", column: "page_id")
+ add_foreign_key "alchemy_elements", "alchemy_pages", column: "page_id", on_update: :cascade, on_delete: :cascade
+ end
+
+ unless foreign_key_exists?("alchemy_nodes", column: "language_id")
+ add_foreign_key "alchemy_nodes", "alchemy_languages", column: "language_id"
+ end
+
+ unless foreign_key_exists?("alchemy_nodes", column: "page_id")
+ add_foreign_key "alchemy_nodes", "alchemy_pages", column: "page_id", on_delete: :cascade
+ end
+
+ unless foreign_key_exists?("alchemy_nodes", column: "site_id")
+ add_foreign_key "alchemy_nodes", "alchemy_sites", column: "site_id", on_delete: :cascade
+ end
+ end
+
+ def down
+ drop_table "alchemy_attachments" if table_exists?("alchemy_attachments")
+ drop_table "alchemy_elements" if table_exists?("alchemy_elements")
+ drop_table "alchemy_elements_alchemy_pages" if table_exists?("alchemy_elements_alchemy_pages")
+ drop_table "alchemy_folded_pages" if table_exists?("alchemy_folded_pages")
+ drop_table "alchemy_languages" if table_exists?("alchemy_languages")
+ drop_table "alchemy_legacy_page_urls" if table_exists?("alchemy_legacy_page_urls")
+ drop_table "alchemy_nodes" if table_exists?("alchemy_nodes")
+ drop_table "alchemy_pages" if table_exists?("alchemy_pages")
+ drop_table "alchemy_pictures" if table_exists?("alchemy_pictures")
+ drop_table "alchemy_sites" if table_exists?("alchemy_sites")
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091718_remove_site_id_from_nodes.alchemy.rb b/spec/dummy/db/migrate/20230119091718_remove_site_id_from_nodes.alchemy.rb
new file mode 100644
index 0000000000..59564ec617
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091718_remove_site_id_from_nodes.alchemy.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+# This migration comes from alchemy (originally 20200504210159)
+class RemoveSiteIdFromNodes < ActiveRecord::Migration[6.0]
+ def up
+ remove_foreign_key :alchemy_nodes, :alchemy_sites
+ remove_index :alchemy_nodes, :site_id
+ remove_column :alchemy_nodes, :site_id, :integer, null: false
+ end
+
+ def down
+ add_column :alchemy_nodes, :site_id, :integer, null: true
+ sql = <<~SQL
+ UPDATE alchemy_nodes
+ SET site_id = (
+ SELECT alchemy_languages.site_id FROM alchemy_languages WHERE alchemy_nodes.language_id = alchemy_languages.id
+ ) WHERE
+ EXISTS (
+ SELECT *
+ FROM alchemy_languages
+ WHERE alchemy_languages.id = alchemy_nodes.language_id
+ );
+ SQL
+
+ connection.execute(sql)
+ change_column :alchemy_nodes, :site_id, :integer, null: false
+ add_index :alchemy_nodes, :site_id
+ add_foreign_key :alchemy_nodes, :alchemy_sites, column: :site_id
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091719_add_language_id_foreign_key_to_alchemy_pages.alchemy.rb b/spec/dummy/db/migrate/20230119091719_add_language_id_foreign_key_to_alchemy_pages.alchemy.rb
new file mode 100644
index 0000000000..01cb10ef48
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091719_add_language_id_foreign_key_to_alchemy_pages.alchemy.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20200505215518)
+class AddLanguageIdForeignKeyToAlchemyPages < ActiveRecord::Migration[6.0]
+ def change
+ add_foreign_key :alchemy_pages, :alchemy_languages, column: :language_id
+ change_column_null :alchemy_pages, :language_id, false, Alchemy::Language.default&.id
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091720_add_menu_type_to_alchemy_nodes.alchemy.rb b/spec/dummy/db/migrate/20230119091720_add_menu_type_to_alchemy_nodes.alchemy.rb
new file mode 100644
index 0000000000..9e98022898
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091720_add_menu_type_to_alchemy_nodes.alchemy.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+# This migration comes from alchemy (originally 20200511113603)
+class AddMenuTypeToAlchemyNodes < ActiveRecord::Migration[6.0]
+ class LocalNode < ActiveRecord::Base
+ self.table_name = :alchemy_nodes
+ acts_as_nested_set scope: :language_id
+
+ def self.root_for(node)
+ return node if node.parent_id.nil?
+
+ root_for(node.parent)
+ end
+ end
+
+ def up
+ add_column :alchemy_nodes, :menu_type, :string
+ LocalNode.all.each do |node|
+ root = LocalNode.root_for(node)
+ menu_type = root.name.parameterize.underscore
+ node.update(menu_type: menu_type)
+ end
+ change_column_null :alchemy_nodes, :menu_type, false
+ end
+
+ def down
+ remove_column :alchemy_nodes, :menu_type
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091721_make_page_layoutpage_null_false.alchemy.rb b/spec/dummy/db/migrate/20230119091721_make_page_layoutpage_null_false.alchemy.rb
new file mode 100644
index 0000000000..c96ca75062
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091721_make_page_layoutpage_null_false.alchemy.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+# This migration comes from alchemy (originally 20200514091507)
+class MakePageLayoutpageNullFalse < ActiveRecord::Migration[6.0]
+ def change
+ change_column_null :alchemy_pages, :layoutpage, false, false
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091722_remove_visible_from_alchemy_pages.alchemy.rb b/spec/dummy/db/migrate/20230119091722_remove_visible_from_alchemy_pages.alchemy.rb
new file mode 100644
index 0000000000..31dd81fb51
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091722_remove_visible_from_alchemy_pages.alchemy.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+# This migration comes from alchemy (originally 20200519073500)
+class RemoveVisibleFromAlchemyPages < ActiveRecord::Migration[6.0]
+ class LocalPage < ActiveRecord::Base
+ self.table_name = "alchemy_pages"
+
+ scope :invisible, -> { where(visible: [false, nil]) }
+ scope :contentpages, -> { where(layoutpage: [false, nil]) }
+ end
+
+ def up
+ if LocalPage.invisible.contentpages.where.not(parent_id: nil).any?
+ abort "You have invisible pages in your database! " \
+ "Please re-structure your page tree before running this migration. " \
+ "You might also downgrade to Alchemy 4.6 and " \
+ "run the `alchemy:upgrade:4.6:restructure_page_tree` rake task."
+ end
+
+ remove_column :alchemy_pages, :visible
+ end
+
+ def down
+ add_column :alchemy_pages, :visible, :boolean, default: false
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091723_create_alchemy_picture_thumbs.alchemy.rb b/spec/dummy/db/migrate/20230119091723_create_alchemy_picture_thumbs.alchemy.rb
new file mode 100644
index 0000000000..08e2235d73
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091723_create_alchemy_picture_thumbs.alchemy.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20200617110713)
+class CreateAlchemyPictureThumbs < ActiveRecord::Migration[6.0]
+ def up
+ return if table_exists?(:alchemy_picture_thumbs)
+
+ create_table :alchemy_picture_thumbs do |t|
+ t.references :picture, foreign_key: { to_table: :alchemy_pictures }, null: false
+ t.string :signature, null: false
+ t.text :uid, null: false
+ end
+ add_index :alchemy_picture_thumbs, :signature, unique: true
+ end
+
+ def down
+ return unless table_exists?(:alchemy_picture_thumbs)
+
+ remove_foreign_key :alchemy_picture_thumbs, :alchemy_pictures, column: :picture_id
+ remove_index :alchemy_picture_thumbs, :signature
+ drop_table :alchemy_picture_thumbs
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091724_remove_tri_state_booleans.alchemy.rb b/spec/dummy/db/migrate/20230119091724_remove_tri_state_booleans.alchemy.rb
new file mode 100644
index 0000000000..e3e7293190
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091724_remove_tri_state_booleans.alchemy.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20200907111332)
+class RemoveTriStateBooleans < ActiveRecord::Migration[6.0]
+ def change
+ change_column_null :alchemy_elements, :public, false, false
+ change_column_default :alchemy_elements, :public, true
+
+ change_column_null :alchemy_elements, :folded, false
+ change_column_null :alchemy_elements, :unique, false
+
+ change_column_null :alchemy_folded_pages, :folded, false
+
+ change_column_null :alchemy_languages, :public, false
+ change_column_null :alchemy_languages, :default, false
+
+ change_column_null :alchemy_pages, :language_root, false, false
+ change_column_default :alchemy_pages, :language_root, false
+
+ change_column_null :alchemy_pages, :restricted, false
+ change_column_null :alchemy_pages, :robot_index, false
+ change_column_null :alchemy_pages, :robot_follow, false
+ change_column_null :alchemy_pages, :sitemap, false
+
+ change_column_null :alchemy_sites, :public, false
+ change_column_null :alchemy_sites, :redirect_to_primary_host, false, false
+ change_column_default :alchemy_sites, :redirect_to_primary_host, false
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091725_create_page_versions.alchemy.rb b/spec/dummy/db/migrate/20230119091725_create_page_versions.alchemy.rb
new file mode 100644
index 0000000000..aac2252468
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091725_create_page_versions.alchemy.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20201207131309)
+class CreatePageVersions < ActiveRecord::Migration[6.0]
+ def change
+ create_table :alchemy_page_versions do |t|
+ t.references :page,
+ null: false,
+ index: true,
+ foreign_key: {
+ to_table: :alchemy_pages,
+ on_delete: :cascade,
+ }
+ t.datetime :public_on
+ t.datetime :public_until
+ t.index [:public_on, :public_until]
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091726_add_page_version_id_to_alchemy_elements.alchemy.rb b/spec/dummy/db/migrate/20230119091726_add_page_version_id_to_alchemy_elements.alchemy.rb
new file mode 100644
index 0000000000..fe63be1735
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091726_add_page_version_id_to_alchemy_elements.alchemy.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20201207135820)
+class AddPageVersionIdToAlchemyElements < ActiveRecord::Migration[6.0]
+ class LocalPage < ActiveRecord::Base
+ self.table_name = :alchemy_pages
+ has_many :elements, class_name: "LocalElement", inverse_of: :page
+ has_many :versions, class_name: "LocalVersion", inverse_of: :page, foreign_key: :page_id
+ end
+
+ class LocalVersion < ActiveRecord::Base
+ self.table_name = :alchemy_page_versions
+ belongs_to :page, class_name: "LocalPage", inverse_of: :versions
+ has_many :elements, class_name: "LocalElement", inverse_of: :versions
+ end
+
+ class LocalElement < ActiveRecord::Base
+ self.table_name = :alchemy_elements
+ belongs_to :page, class_name: "LocalPage", inverse_of: :elements
+ belongs_to :page_version, class_name: "LocalVersion", inverse_of: :elements
+ end
+
+ def change
+ add_reference :alchemy_elements, :page_version,
+ index: false,
+ foreign_key: {
+ to_table: :alchemy_page_versions,
+ on_delete: :cascade,
+ }
+ add_index :alchemy_elements, [:page_version_id, :parent_element_id],
+ name: "idx_alchemy_elements_on_page_version_id_and_parent_element_id"
+ add_index :alchemy_elements, [:page_version_id, :position],
+ name: "idx_alchemy_elements_on_page_version_id_and_position"
+
+ # Add a page version for each page so we can add a not null constraint
+ reversible do |dir|
+ dir.up do
+ say_with_time "Create draft version for each page." do
+ LocalPage.find_each do |page|
+ next if page.versions.any?
+
+ page.versions.create!.tap do |version|
+ Alchemy::Element.where(page_id: page.id).update_all(page_version_id: version.id)
+ end
+ end
+ LocalVersion.count
+ end
+ end
+ end
+
+ change_column_null :alchemy_elements, :page_version_id, false
+
+ # Remove the existing page relation
+ remove_reference :alchemy_elements, :page,
+ null: false,
+ index: false,
+ foreign_key: {
+ to_table: :alchemy_pages,
+ on_delete: :cascade,
+ on_update: :cascade,
+ }
+ if index_exists? :alchemy_elements,
+ :parent_element_id,
+ name: "index_alchemy_elements_on_page_id_and_parent_element_id"
+ remove_index :alchemy_elements,
+ column: [:parent_element_id],
+ name: "index_alchemy_elements_on_page_id_and_parent_element_id"
+ end
+ if index_exists? :alchemy_elements,
+ :position,
+ name: "index_elements_on_page_id_and_position"
+ remove_index :alchemy_elements,
+ column: [:position],
+ name: "index_elements_on_page_id_and_position"
+ end
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091727_rename_public_on_and_public_until_on_alchemy_pages.alchemy.rb b/spec/dummy/db/migrate/20230119091727_rename_public_on_and_public_until_on_alchemy_pages.alchemy.rb
new file mode 100644
index 0000000000..ff8c1df65e
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091727_rename_public_on_and_public_until_on_alchemy_pages.alchemy.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20210205143548)
+class RenamePublicOnAndPublicUntilOnAlchemyPages < ActiveRecord::Migration[6.0]
+ def change
+ remove_index :alchemy_pages, column: [:public_on, :public_until],
+ name: "index_alchemy_pages_on_public_on_and_public_until"
+ rename_column :alchemy_pages, :public_on, :legacy_public_on
+ rename_column :alchemy_pages, :public_until, :legacy_public_until
+ end
+end
diff --git a/spec/dummy/db/migrate/20230119091728_create_alchemy_ingredients.alchemy.rb b/spec/dummy/db/migrate/20230119091728_create_alchemy_ingredients.alchemy.rb
new file mode 100644
index 0000000000..19d40e5413
--- /dev/null
+++ b/spec/dummy/db/migrate/20230119091728_create_alchemy_ingredients.alchemy.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20210508091432)
+class CreateAlchemyIngredients < ActiveRecord::Migration[6.0]
+ def change
+ create_table :alchemy_ingredients do |t|
+ t.references :element, null: false, foreign_key: { to_table: :alchemy_elements, on_delete: :cascade }
+ t.string :type, index: true, null: false
+ t.string :role, null: false
+ t.text :value
+ if ActiveRecord::Migration.connection.adapter_name.match?(/postgres/i)
+ t.jsonb :data, default: {}
+ else
+ t.json :data
+ end
+ t.belongs_to :related_object, null: true, polymorphic: true, index: false
+ t.index [:element_id, :role], unique: true
+ t.index [:related_object_id, :related_object_type], name: "idx_alchemy_ingredient_relation"
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/dummy/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb b/spec/dummy/db/migrate/20230119091729_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.alchemy.rb
similarity index 81%
rename from spec/dummy/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb
rename to spec/dummy/db/migrate/20230119091729_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.alchemy.rb
index 0a6a9322a5..ab4a5f553f 100644
--- a/spec/dummy/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb
+++ b/spec/dummy/db/migrate/20230119091729_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.alchemy.rb
@@ -1,3 +1,6 @@
+# frozen_string_literal: true
+
+# This migration comes from alchemy (originally 20220514072456)
class RestrictOnDeletePageIdForeignKeyFromAlchemyNodes < ActiveRecord::Migration[6.0]
def up
remove_foreign_key :alchemy_nodes, :alchemy_pages
diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb
index 56899f3374..d62183e5fc 100644
--- a/spec/dummy/db/schema.rb
+++ b/spec/dummy/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2022_08_31_084620) do
+ActiveRecord::Schema[7.0].define(version: 2023_01_19_091729) do
create_table "alchemy_attachments", force: :cascade do |t|
t.string "name"
t.string "file_name"
@@ -26,15 +26,6 @@
t.index ["updater_id"], name: "index_alchemy_attachments_on_updater_id"
end
- create_table "alchemy_contents", force: :cascade do |t|
- t.string "name"
- t.string "essence_type", null: false
- t.integer "essence_id", null: false
- t.integer "element_id", null: false
- t.index ["element_id"], name: "index_alchemy_contents_on_element_id"
- t.index ["essence_type", "essence_id"], name: "index_alchemy_contents_on_essence_type_and_essence_id", unique: true
- end
-
create_table "alchemy_elements", force: :cascade do |t|
t.string "name"
t.integer "position"
@@ -62,114 +53,6 @@
t.index ["page_id"], name: "index_alchemy_elements_alchemy_pages_on_page_id"
end
- create_table "alchemy_essence_audios", force: :cascade do |t|
- t.integer "attachment_id"
- t.boolean "controls", default: true, null: false
- t.boolean "autoplay", default: false
- t.boolean "loop", default: false, null: false
- t.boolean "muted", default: false, null: false
- t.index ["attachment_id"], name: "index_alchemy_essence_audios_on_attachment_id"
- end
-
- create_table "alchemy_essence_booleans", force: :cascade do |t|
- t.boolean "value"
- t.index ["value"], name: "index_alchemy_essence_booleans_on_value"
- end
-
- create_table "alchemy_essence_dates", force: :cascade do |t|
- t.datetime "date", precision: nil
- end
-
- create_table "alchemy_essence_files", force: :cascade do |t|
- t.integer "attachment_id"
- t.string "title"
- t.string "css_class"
- t.string "link_text"
- t.index ["attachment_id"], name: "index_alchemy_essence_files_on_attachment_id"
- end
-
- create_table "alchemy_essence_headlines", force: :cascade do |t|
- t.text "body"
- t.integer "level"
- t.integer "size"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- end
-
- create_table "alchemy_essence_htmls", force: :cascade do |t|
- t.text "source"
- end
-
- create_table "alchemy_essence_links", force: :cascade do |t|
- t.string "link"
- t.string "link_title"
- t.string "link_target"
- t.string "link_class_name"
- end
-
- create_table "alchemy_essence_nodes", force: :cascade do |t|
- t.integer "node_id"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["node_id"], name: "index_alchemy_essence_nodes_on_node_id"
- end
-
- create_table "alchemy_essence_pages", force: :cascade do |t|
- t.integer "page_id"
- t.index ["page_id"], name: "index_alchemy_essence_pages_on_page_id"
- end
-
- create_table "alchemy_essence_pictures", force: :cascade do |t|
- t.integer "picture_id"
- t.string "caption"
- t.string "title"
- t.string "alt_tag"
- t.string "link"
- t.string "link_class_name"
- t.string "link_title"
- t.string "css_class"
- t.string "link_target"
- t.string "crop_from"
- t.string "crop_size"
- t.string "render_size"
- t.index ["picture_id"], name: "index_alchemy_essence_pictures_on_picture_id"
- end
-
- create_table "alchemy_essence_richtexts", force: :cascade do |t|
- t.text "body"
- t.text "stripped_body"
- t.boolean "public", default: false, null: false
- t.text "sanitized_body"
- end
-
- create_table "alchemy_essence_selects", force: :cascade do |t|
- t.string "value"
- t.index ["value"], name: "index_alchemy_essence_selects_on_value"
- end
-
- create_table "alchemy_essence_texts", force: :cascade do |t|
- t.text "body"
- t.string "link"
- t.string "link_title"
- t.string "link_class_name"
- t.boolean "public", default: false, null: false
- t.string "link_target"
- end
-
- create_table "alchemy_essence_videos", force: :cascade do |t|
- t.integer "attachment_id"
- t.string "width"
- t.string "height"
- t.boolean "allow_fullscreen", default: true, null: false
- t.boolean "autoplay", default: false, null: false
- t.boolean "controls", default: true, null: false
- t.boolean "loop", default: false, null: false
- t.boolean "muted", default: false, null: false
- t.string "preload"
- t.boolean "playsinline", default: false, null: false
- t.index ["attachment_id"], name: "index_alchemy_essence_videos_on_attachment_id"
- end
-
create_table "alchemy_folded_pages", force: :cascade do |t|
t.integer "page_id", null: false
t.integer "user_id", null: false
@@ -341,10 +224,6 @@
t.datetime "updated_at", precision: nil, null: false
end
- create_table "dummy_models", force: :cascade do |t|
- t.string "data"
- end
-
create_table "dummy_users", force: :cascade do |t|
t.string "email"
t.string "password"
@@ -397,10 +276,7 @@
t.string "name"
end
- add_foreign_key "alchemy_contents", "alchemy_elements", column: "element_id", on_update: :cascade, on_delete: :cascade
add_foreign_key "alchemy_elements", "alchemy_page_versions", column: "page_version_id", on_delete: :cascade
- add_foreign_key "alchemy_essence_nodes", "alchemy_nodes", column: "node_id"
- add_foreign_key "alchemy_essence_pages", "alchemy_pages", column: "page_id"
add_foreign_key "alchemy_ingredients", "alchemy_elements", column: "element_id", on_delete: :cascade
add_foreign_key "alchemy_nodes", "alchemy_languages", column: "language_id"
add_foreign_key "alchemy_nodes", "alchemy_pages", column: "page_id", on_delete: :restrict
diff --git a/spec/features/admin/edit_elements_feature_spec.rb b/spec/features/admin/edit_elements_feature_spec.rb
index 165a7b3d75..125703c5fa 100644
--- a/spec/features/admin/edit_elements_feature_spec.rb
+++ b/spec/features/admin/edit_elements_feature_spec.rb
@@ -134,49 +134,47 @@
end
end
- {content: "name", ingredient: "role"}.each do |type, name_field|
- describe "With an element that has #{type} groups" do
- let(:element) { create(:alchemy_element, page: a_page, name: "element_with_#{type}_groups") }
-
- # Need to be on page editor rather than just admin_elements in order to have JS interaction
- before { visit alchemy.edit_admin_page_path(element.page) }
-
- scenario "collapsed #{type} groups shown", :js do
- # No group content initially visible
- expect(page).not_to have_selector(".content-group-contents", visible: true)
-
- page.find("a#element_#{element.id}_content_group_details_header", text: "Details").click
- # 'Details' group content visible
- expect(page).to have_selector("#element_#{element.id}_content_group_details", visible: true)
- within("#element_#{element.id}_content_group_details") do
- expect(page).to have_selector("[data-#{type}-#{name_field}='description']")
- expect(page).to have_selector("[data-#{type}-#{name_field}='key_words']")
- end
- expect(page).to have_selector("#element_#{element.id}_content_group_details", visible: true)
-
- # 'Size' group content not visible
- expect(page).not_to have_selector("#element_#{element.id}_content_group_size", visible: true)
+ describe "With an element that has ingredient groups" do
+ let(:element) { create(:alchemy_element, page: a_page, name: "element_with_ingredient_groups") }
+
+ # Need to be on page editor rather than just admin_elements in order to have JS interaction
+ before { visit alchemy.edit_admin_page_path(element.page) }
+
+ scenario "collapsed ingredient groups shown", :js do
+ # No group ingredient initially visible
+ expect(page).not_to have_selector(".ingredient-group-ingredients", visible: true)
+
+ page.find("a#element_#{element.id}_ingredient_group_details_header", text: "Details").click
+ # 'Details' group ingredient visible
+ expect(page).to have_selector("#element_#{element.id}_ingredient_group_details", visible: true)
+ within("#element_#{element.id}_ingredient_group_details") do
+ expect(page).to have_selector("[data-ingredient-role='description']")
+ expect(page).to have_selector("[data-ingredient-role='key_words']")
+ end
+ expect(page).to have_selector("#element_#{element.id}_ingredient_group_details", visible: true)
- page.find("a#element_#{element.id}_content_group_size_header", text: "Size").click
- # 'Size' group now visible
- expect(page).to have_selector("#element_#{element.id}_content_group_size", visible: true)
- within("#element_#{element.id}_content_group_size") do
- expect(page).to have_selector("[data-#{type}-#{name_field}='width']")
- expect(page).to have_selector("[data-#{type}-#{name_field}='height']")
- end
+ # 'Size' group ingredient not visible
+ expect(page).not_to have_selector("#element_#{element.id}_ingredient_group_size", visible: true)
- page.find("a#element_#{element.id}_content_group_size_header", text: "Size").click
- # 'Size' group hidden
- expect(page).not_to have_selector("#element_#{element.id}_content_group_size", visible: true)
+ page.find("a#element_#{element.id}_ingredient_group_size_header", text: "Size").click
+ # 'Size' group now visible
+ expect(page).to have_selector("#element_#{element.id}_ingredient_group_size", visible: true)
+ within("#element_#{element.id}_ingredient_group_size") do
+ expect(page).to have_selector("[data-ingredient-role='width']")
+ expect(page).to have_selector("[data-ingredient-role='height']")
end
- scenario "expanded content groups persist between visits", :js do
- expect(page).not_to have_selector("#element_#{element.id}_content_group_details", visible: true)
- page.find("a#element_#{element.id}_content_group_details_header", text: "Details").click
- expect(page).to have_selector("#element_#{element.id}_content_group_details", visible: true)
- visit alchemy.edit_admin_page_path(element.page)
- expect(page).to have_selector("#element_#{element.id}_content_group_details", visible: true)
- end
+ page.find("a#element_#{element.id}_ingredient_group_size_header", text: "Size").click
+ # 'Size' group hidden
+ expect(page).not_to have_selector("#element_#{element.id}_ingredient_group_size", visible: true)
+ end
+
+ scenario "expanded ingredient groups persist between visits", :js do
+ expect(page).not_to have_selector("#element_#{element.id}_ingredient_group_details", visible: true)
+ page.find("a#element_#{element.id}_ingredient_group_details_header", text: "Details").click
+ expect(page).to have_selector("#element_#{element.id}_ingredient_group_details", visible: true)
+ visit alchemy.edit_admin_page_path(element.page)
+ expect(page).to have_selector("#element_#{element.id}_ingredient_group_details", visible: true)
end
end
end
diff --git a/spec/features/admin/link_overlay_spec.rb b/spec/features/admin/link_overlay_spec.rb
index 3cab3bbe16..00f74c7e51 100644
--- a/spec/features/admin/link_overlay_spec.rb
+++ b/spec/features/admin/link_overlay_spec.rb
@@ -45,17 +45,19 @@
end
let!(:article) do
- create(:alchemy_element,
+ create(
+ :alchemy_element,
name: "article",
page_version: page1.draft_version,
- autogenerate_contents: true)
+ autogenerate_ingredients: true,
+ )
end
it "should be possible to link a page" do
visit edit_admin_page_path(page1)
within "#element_#{article.id}" do
- fill_in "Headline", with: "Link me"
+ fill_in "Intro", with: "Link me"
click_link "Link text"
end
diff --git a/spec/features/admin/node_select_feature_spec.rb b/spec/features/admin/node_select_feature_spec.rb
index fa9b276bd0..45389a7040 100644
--- a/spec/features/admin/node_select_feature_spec.rb
+++ b/spec/features/admin/node_select_feature_spec.rb
@@ -21,13 +21,13 @@
it "restricts to the site/language of the page the element is on" do
visit alchemy.admin_elements_path(page_version_id: element.page_version_id)
- select2_search("test", element_id: element.id, content_name: "menu")
+ select2_search("test", element_id: element.id, ingredient_role: "menu")
within "#element_#{element.id}" do
click_on("Save")
end
expect(page).to have_content("Saved", wait: 5)
- expect(element.reload.ingredient(:menu)).to eq(node)
+ expect(element.reload.value_for(:menu)).to eq(node)
end
end
end
diff --git a/spec/features/admin/page_editing_feature_spec.rb b/spec/features/admin/page_editing_feature_spec.rb
index d4d18cab6e..c8c9f3e1a4 100644
--- a/spec/features/admin/page_editing_feature_spec.rb
+++ b/spec/features/admin/page_editing_feature_spec.rb
@@ -155,32 +155,32 @@ class FooPreviewSource < Alchemy::Admin::PreviewUrl; end
create(:alchemy_page, page_layout: "everything", autogenerate_elements: true)
end
- it "renders essence editors for all element contents" do
+ it "renders editors for all element ingredients" do
visit alchemy.admin_elements_path(page_version_id: everything_page.draft_version.id)
- expect(page).to have_selector("div.content_editor.essence_boolean")
- expect(page).to have_selector("div.content_editor.essence_date")
- expect(page).to have_selector("div.content_editor.essence_file")
- expect(page).to have_selector("div.content_editor.essence_html")
- expect(page).to have_selector("div.content_editor.essence_link")
- expect(page).to have_selector("div.content_editor.essence_picture")
- expect(page).to have_selector("div.content_editor.essence_richtext")
- expect(page).to have_selector("div.content_editor.essence_select")
- expect(page).to have_selector("div.content_editor.essence_text")
+ expect(page).to have_selector("div.ingredient-editor.boolean")
+ expect(page).to have_selector("div.ingredient-editor.datetime")
+ expect(page).to have_selector("div.ingredient-editor.file")
+ expect(page).to have_selector("div.ingredient-editor.html")
+ expect(page).to have_selector("div.ingredient-editor.link")
+ expect(page).to have_selector("div.ingredient-editor.picture")
+ expect(page).to have_selector("div.ingredient-editor.richtext")
+ expect(page).to have_selector("div.ingredient-editor.select")
+ expect(page).to have_selector("div.ingredient-editor.text")
end
- it "renders data attribute based on content name" do
+ it "renders data attribute based on ingredient role" do
visit alchemy.admin_elements_path(page_version_id: everything_page.draft_version.id)
- expect(page).to have_selector("div[data-content-name=essence_boolean]")
- expect(page).to have_selector("div[data-content-name=essence_date]")
- expect(page).to have_selector("div[data-content-name=essence_file]")
- expect(page).to have_selector("div[data-content-name=essence_html]")
- expect(page).to have_selector("div[data-content-name=essence_link]")
- expect(page).to have_selector("div[data-content-name=essence_picture]")
- expect(page).to have_selector("div[data-content-name=essence_richtext]")
- expect(page).to have_selector("div[data-content-name=essence_select]")
- expect(page).to have_selector("div[data-content-name=essence_text]")
+ expect(page).to have_selector("div[data-ingredient-role=boolean]")
+ expect(page).to have_selector("div[data-ingredient-role=datetime]")
+ expect(page).to have_selector("div[data-ingredient-role=file]")
+ expect(page).to have_selector("div[data-ingredient-role=html]")
+ expect(page).to have_selector("div[data-ingredient-role=link]")
+ expect(page).to have_selector("div[data-ingredient-role=picture]")
+ expect(page).to have_selector("div[data-ingredient-role=richtext]")
+ expect(page).to have_selector("div[data-ingredient-role=select]")
+ expect(page).to have_selector("div[data-ingredient-role=text]")
end
end
end
diff --git a/spec/features/admin/picture_assignment_overlay_spec.rb b/spec/features/admin/picture_assignment_overlay_spec.rb
index a62a91a5f9..e178d282be 100644
--- a/spec/features/admin/picture_assignment_overlay_spec.rb
+++ b/spec/features/admin/picture_assignment_overlay_spec.rb
@@ -9,11 +9,11 @@
describe "assigning an image" do
let!(:picture) { create(:alchemy_picture) }
- let(:element) { create(:alchemy_element, :with_contents, name: "header") }
- let(:content) { element.contents.last }
+ let(:element) { create(:alchemy_element, :with_ingredients, name: "header") }
+ let(:ingredient) { element.ingredients.last }
- scenario "it has link to assign picture to content" do
- visit alchemy.admin_pictures_path(form_field_id: "contents_#{content.id}_picture_id")
+ scenario "it has link to assign picture to ingredient" do
+ visit alchemy.admin_pictures_path(form_field_id: "ingredients_#{ingredient.id}_picture_id")
expect(page).to have_css %(a[data-method="put"][href*="/admin/pictures/#{picture.id}/assign"])
end
end
diff --git a/spec/features/admin/resources_integration_spec.rb b/spec/features/admin/resources_integration_spec.rb
index cf13fc6c22..ba67914615 100644
--- a/spec/features/admin/resources_integration_spec.rb
+++ b/spec/features/admin/resources_integration_spec.rb
@@ -3,7 +3,7 @@
require "rails_helper"
RSpec.describe "Resources", type: :system do
- let(:event) { create(:event) }
+ let(:event) { create(:event) }
let(:second_event) { create(:event, name: "My second Event", entrance_fee: 12.32) }
before { authorize_user(:as_admin) }
@@ -294,7 +294,7 @@
end
context "with tagged events in the index view" do
- let!(:event) { create(:event, name: "Casablanca", tag_list: "Matinee") }
+ let!(:event) { create(:event, name: "Casablanca", tag_list: "Matinee") }
let!(:second_event) { create(:event, name: "Die Hard IX", tag_list: "Late Show") }
before { visit "/admin/events" }
@@ -334,19 +334,19 @@
# Here we visit the pages manually, as we don't want to test the JS here.
visit "/admin/events?filter[start]=starting_today"
- expect(page).to have_content("Car Expo")
+ expect(page).to have_content("Car Expo")
expect(page).to_not have_content("Hovercar Expo")
expect(page).to_not have_content("Horse Expo")
visit "/admin/events?filter[start]=future"
- expect(page).to have_content("Hovercar Expo")
+ expect(page).to have_content("Hovercar Expo")
expect(page).to_not have_content("Car Expo")
expect(page).to_not have_content("Horse Expo")
# Keep the filter when editing an event
click_link "Edit"
click_button "Save"
- expect(page).to have_content("Hovercar Expo")
+ expect(page).to have_content("Hovercar Expo")
expect(page).to_not have_content("Car Expo")
expect(page).to_not have_content("Horse Expo")
end
diff --git a/spec/features/page_feature_spec.rb b/spec/features/page_feature_spec.rb
index 622faa8e19..07eedea92c 100644
--- a/spec/features/page_feature_spec.rb
+++ b/spec/features/page_feature_spec.rb
@@ -37,13 +37,13 @@
context "rendered" do
let(:public_page) { create(:alchemy_page, :public, autogenerate_elements: true) }
let(:article) { public_page.elements.find_by_name("article") }
- let(:essence) { article.content_by_name("intro").essence }
+ let(:ingredient) { article.ingredient_by_role("intro") }
before do
- essence.update_columns(body: "Welcome to Peters Petshop", public: true)
+ ingredient.update_columns(value: "Welcome to Peters Petshop")
end
- it "should include all its elements and contents" do
+ it "should include all its elements and ingredients" do
visit "/#{public_page.urlname}"
within("div#content div.article div.intro") do
expect(page).to have_content("Welcome to Peters Petshop")
diff --git a/spec/helpers/alchemy/admin/base_helper_spec.rb b/spec/helpers/alchemy/admin/base_helper_spec.rb
index abab59dd87..9169850c55 100644
--- a/spec/helpers/alchemy/admin/base_helper_spec.rb
+++ b/spec/helpers/alchemy/admin/base_helper_spec.rb
@@ -9,9 +9,9 @@ module Alchemy
before { allow(helper).to receive(:can?).and_return(true) }
it "renders a toolbar button" do
- expect(helper.toolbar_button(
- url: admin_dashboard_path,
- )).to match / "headline",
- "contents" => [],
+ "ingredients" => [],
}]
end
diff --git a/spec/helpers/alchemy/admin/essences_helper_spec.rb b/spec/helpers/alchemy/admin/essences_helper_spec.rb
deleted file mode 100644
index d3d8958c30..0000000000
--- a/spec/helpers/alchemy/admin/essences_helper_spec.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-describe Alchemy::Admin::EssencesHelper do
- include Alchemy::Admin::ElementsHelper
-
- let(:element) do
- create(:alchemy_element, :with_contents, name: "article")
- end
-
- describe "#essence_picture_thumbnail" do
- let(:essence) do
- create(:alchemy_essence_picture)
- end
-
- let(:content) do
- create(:alchemy_content, essence: essence)
- end
-
- it "should return an image tag with thumbnail url from essence" do
- expect(essence).to receive(:thumbnail_url).and_call_original
- expect(helper.essence_picture_thumbnail(content)).to \
- have_selector("img[src].img_paddingtop")
- end
-
- context "when given content has no ingredient" do
- before { allow(content).to receive(:ingredient).and_return(nil) }
-
- it "should return nil" do
- expect(helper.essence_picture_thumbnail(content)).to eq(nil)
- end
- end
- end
-
- describe "#edit_picture_dialog_size" do
- let(:content) { build_stubbed(:alchemy_content) }
-
- subject { edit_picture_dialog_size(content) }
-
- context "with content having setting caption_as_textarea being true and sizes set" do
- before do
- allow(content).to receive(:settings) do
- {
- caption_as_textarea: true,
- sizes: ["100x100", "200x200"],
- }
- end
-
- it { is_expected.to eq("380x320") }
- end
- end
-
- context "with content having setting caption_as_textarea being true and no sizes set" do
- before do
- allow(content).to receive(:settings) do
- {
- caption_as_textarea: true,
- }
- end
-
- it { is_expected.to eq("380x300") }
- end
- end
-
- context "with content having setting caption_as_textarea being false and sizes set" do
- before do
- allow(content).to receive(:settings) do
- {
- caption_as_textarea: false,
- sizes: ["100x100", "200x200"],
- }
- end
-
- it { is_expected.to eq("380x290") }
- end
- end
-
- context "with content having setting caption_as_textarea being false and no sizes set" do
- before do
- allow(content).to receive(:settings) do
- {
- caption_as_textarea: false,
- }
- end
-
- it { is_expected.to eq("380x255") }
- end
- end
- end
-end
diff --git a/spec/helpers/alchemy/admin/ingredients_helper_spec.rb b/spec/helpers/alchemy/admin/ingredients_helper_spec.rb
index e2f704e402..a3f202d519 100644
--- a/spec/helpers/alchemy/admin/ingredients_helper_spec.rb
+++ b/spec/helpers/alchemy/admin/ingredients_helper_spec.rb
@@ -3,7 +3,7 @@
require "rails_helper"
describe Alchemy::Admin::IngredientsHelper do
- let(:element) { build_stubbed(:alchemy_element, name: "element_with_ingredients") }
+ let(:element) { build_stubbed(:alchemy_element, name: "article") }
let(:ingredient) { Alchemy::Ingredients::Text.new(role: "headline", element: element) }
let(:ingredient_editor) { Alchemy::IngredientEditor.new(ingredient) }
@@ -55,7 +55,7 @@
mock_model "Alchemy::Ingredients::Text",
role: "intro",
definition: {},
- name_for_label: "Intro",
+ translated_role: "Intro",
has_validations?: false,
deprecated?: false,
has_warnings?: true,
@@ -74,7 +74,7 @@
mock_model "Alchemy::Ingredients::Text",
role: "intro",
definition: { name: "intro", type: "Text", deprecated: true },
- name_for_label: "Intro",
+ translated_role: "Intro",
has_validations?: false,
deprecated?: true,
has_warnings?: true,
diff --git a/spec/helpers/alchemy/elements_block_helper_spec.rb b/spec/helpers/alchemy/elements_block_helper_spec.rb
index ed20881d05..02826c0074 100644
--- a/spec/helpers/alchemy/elements_block_helper_spec.rb
+++ b/spec/helpers/alchemy/elements_block_helper_spec.rb
@@ -36,7 +36,7 @@ module Alchemy
to have_css "#{expected_wrapper_tag}[data-element-tags='foo, bar']"
end
- it "should include the contents rendered by the block passed to it" do
+ it "should include the ingredients rendered by the block passed to it" do
expect(element_view_for(element) do
"view"
end).to have_content "view"
@@ -68,23 +68,6 @@ module Alchemy
end
describe "#render" do
- context "with element having contents" do
- let(:element) { create(:alchemy_element, :with_contents) }
- let(:content) { element.content_by_name(:headline) }
-
- it "delegates to Rails' render helper" do
- expect(scope).to receive(:render).with(content, {
- options: {
- foo: "bar",
- },
- html_options: {},
- })
- Alchemy::Deprecation.silence do
- subject.render(:headline, foo: "bar")
- end
- end
- end
-
context "with element having ingredients" do
let(:element) { create(:alchemy_element, :with_ingredients) }
let(:ingredient) { element.ingredient_by_role(:headline) }
@@ -101,36 +84,6 @@ module Alchemy
end
end
- describe "#content" do
- it "should delegate to the element's #content_by_name method" do
- expect(element).to receive(:content_by_name).with(:title)
- Alchemy::Deprecation.silence do
- subject.content :title
- end
- end
- end
-
- describe "#ingredient" do
- context "with element having contents" do
- it "should delegate to the element's #ingredient method" do
- expect(element).to receive(:ingredient).with(:title)
- subject.ingredient(:title)
- end
- end
-
- context "with element having ingredients" do
- let(:element) { create(:alchemy_element, :with_ingredients) }
- let(:ingredient) { element.ingredient_by_role(:headline) }
-
- it "should return the ingredients value" do
- Alchemy::Deprecation.silenced do
- expect(ingredient).to receive(:value).and_call_original
- subject.ingredient(:headline)
- end
- end
- end
- end
-
describe "#value" do
let(:element) { create(:alchemy_element, :with_ingredients) }
let(:ingredient) { element.ingredients.first }
@@ -142,13 +95,6 @@ module Alchemy
end
describe "#has?" do
- context "with element having contents" do
- it "should delegate to the element's #has_ingredient? method" do
- expect(element).to receive(:has_ingredient?).with(:title)
- subject.has?(:title)
- end
- end
-
context "with element having ingredients" do
let(:element) { create(:alchemy_element, :with_ingredients) }
let(:ingredient) { element.ingredients.first }
@@ -160,18 +106,6 @@ module Alchemy
end
end
- describe "#essence" do
- it "should provide the specified content essence" do
- expect(subject).to receive(:content).with(:title) do
- mock_model("Content", essence: mock_model("EssenceText"))
- end
-
- Alchemy::Deprecation.silence do
- subject.essence :title
- end
- end
- end
-
describe "#ingredient_by_role" do
let(:element) { create(:alchemy_element, :with_ingredients) }
let(:ingredient) { element.ingredient_by_role(:headline) }
diff --git a/spec/helpers/alchemy/elements_helper_spec.rb b/spec/helpers/alchemy/elements_helper_spec.rb
index 8c6fbe2885..c79ac516b6 100644
--- a/spec/helpers/alchemy/elements_helper_spec.rb
+++ b/spec/helpers/alchemy/elements_helper_spec.rb
@@ -23,7 +23,7 @@ module Alchemy
context "with element record given" do
let(:element) do
- create(:alchemy_element, :with_contents, name: "headline")
+ create(:alchemy_element, :with_ingredients, name: "headline")
end
it "renders the element's view partial" do
diff --git a/spec/helpers/alchemy/pages_helper_spec.rb b/spec/helpers/alchemy/pages_helper_spec.rb
index f3b01d7044..ec32289706 100644
--- a/spec/helpers/alchemy/pages_helper_spec.rb
+++ b/spec/helpers/alchemy/pages_helper_spec.rb
@@ -384,14 +384,5 @@ module Alchemy
end
end
end
-
- describe "#picture_essence_caption" do
- let(:essence) { mock_model("EssencePicture", caption: "my caption") }
- let(:content) { mock_model("Content", essence: essence) }
-
- it "should return the caption of the contents essence" do
- expect(helper.picture_essence_caption(content)).to eq "my caption"
- end
- end
end
end
diff --git a/spec/libraries/alchemy/upgrader/tasks/ingredients_migrator_spec.rb b/spec/libraries/alchemy/upgrader/tasks/ingredients_migrator_spec.rb
deleted file mode 100644
index 4623f12e55..0000000000
--- a/spec/libraries/alchemy/upgrader/tasks/ingredients_migrator_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-require "alchemy/upgrader/tasks/ingredients_migrator"
-
-RSpec.describe Alchemy::Upgrader::Tasks::IngredientsMigrator do
- let!(:element) do
- FactoryBot.create(
- :alchemy_element,
- name: "element_with_ingredients",
- autogenerate_ingredients: false,
- contents: [content1, content2]
- )
- end
-
- let(:content1) { Alchemy::Content.new(name: "headline", essence: headline) }
- let(:headline) { FactoryBot.create(:alchemy_essence_text) }
- let(:content2) { Alchemy::Content.new(name: "text", essence: text) }
- let(:text) { Alchemy::EssenceRichtext.new(body: "Hello World") }
-
- subject { described_class.new.create_ingredients }
-
- it "changes existing elements with contents and essences to ingredients" do
- expect(Alchemy::Content.count).to eq(2)
- expect(Alchemy::Ingredient.count).to eq(0)
-
- subject
-
- expect(Alchemy::Content.count).to eq(0)
- expect(Alchemy::Ingredient.count).to eq(2)
- end
-end
diff --git a/spec/libraries/permissions_spec.rb b/spec/libraries/permissions_spec.rb
index 8cb67e47bb..08758ba0b5 100644
--- a/spec/libraries/permissions_spec.rb
+++ b/spec/libraries/permissions_spec.rb
@@ -16,8 +16,6 @@
let(:restricted_page) { build(:alchemy_page, :public, restricted: true) }
let(:published_element) { mock_model(Alchemy::Element, restricted?: false, public?: true) }
let(:restricted_element) { mock_model(Alchemy::Element, restricted?: true, public?: true) }
- let(:published_content) { mock_model(Alchemy::Content, restricted?: false, public?: true) }
- let(:restricted_content) { mock_model(Alchemy::Content, restricted?: true, public?: true) }
context "A guest user" do
let(:user) { nil }
@@ -45,13 +43,6 @@
is_expected.to be_able_to(:index, published_element)
is_expected.not_to be_able_to(:index, restricted_element)
end
-
- it "can only see public not restricted contents" do
- is_expected.to be_able_to(:show, published_content)
- is_expected.not_to be_able_to(:show, restricted_content)
- is_expected.to be_able_to(:index, published_content)
- is_expected.not_to be_able_to(:index, restricted_content)
- end
end
context "A member" do
@@ -80,13 +71,6 @@
is_expected.to be_able_to(:index, published_element)
is_expected.to be_able_to(:index, restricted_element)
end
-
- it "can see public restricted contents" do
- is_expected.to be_able_to(:show, published_content)
- is_expected.to be_able_to(:show, restricted_content)
- is_expected.to be_able_to(:index, published_content)
- is_expected.to be_able_to(:index, restricted_content)
- end
end
context "An author" do
@@ -131,15 +115,7 @@
is_expected.to be_able_to(:url, Alchemy::Picture)
end
- it "can manage contents" do
- is_expected.to be_able_to(:manage, Alchemy::Content)
- end
-
- it "can manage essences" do
- is_expected.to be_able_to(:manage, Alchemy::EssenceAudio)
- is_expected.to be_able_to(:manage, Alchemy::EssenceFile)
- is_expected.to be_able_to(:manage, Alchemy::EssencePicture)
- is_expected.to be_able_to(:manage, Alchemy::EssenceVideo)
+ it "can manage ingredients" do
is_expected.to be_able_to(:manage, Alchemy::Ingredient)
end
diff --git a/spec/libraries/template_tracker_spec.rb b/spec/libraries/template_tracker_spec.rb
index 51f1ee6ce8..168832ae2d 100644
--- a/spec/libraries/template_tracker_spec.rb
+++ b/spec/libraries/template_tracker_spec.rb
@@ -10,7 +10,7 @@ module CacheDigests
describe "#dependencies" do
context "with alchemy/pages/show given as template name" do
let(:name) { "alchemy/pages/show" }
- before { allow(PageLayout).to receive(:all).and_return([{"name" => "intro"}, {"name" => "contact"}]) }
+ before { allow(PageLayout).to receive(:all).and_return([{ "name" => "intro" }, { "name" => "contact" }]) }
it "returns all page layout view partial names" do
is_expected.to include("alchemy/page_layouts/_intro", "alchemy/page_layouts/_contact")
@@ -19,23 +19,36 @@ module CacheDigests
context "with a page layout given as template name" do
let(:name) { "alchemy/page_layouts/_intro" }
- let(:page_layout) { {"name" => "intro", "elements" => ["text"]} }
+ let(:page_layout) { { "name" => "intro", "elements" => ["text"] } }
before { allow(PageLayout).to receive(:get).and_return(page_layout) }
it "returns all element layout view partial names for that layout" do
- is_expected.to include("alchemy/elements/_text_view")
+ is_expected.to include("alchemy/elements/_text")
end
end
context "with an element view given as name" do
- let(:name) { "alchemy/elements/_text_view" }
- let(:elements) { [{"name" => "text", "contents" => [{"type" => "EssenceText"}]}] }
+ let(:name) { "alchemy/elements/_text" }
+
+ let(:elements) do
+ [
+ {
+ "name" => "text",
+ "ingredients" => [
+ {
+ "role" => "text",
+ "type" => "Text",
+ },
+ ],
+ },
+ ]
+ end
context "that is having a definition" do
before { allow(Element).to receive(:definitions).and_return(elements) }
- it "returns all essence layout view partial names for that element" do
- is_expected.to include("alchemy/essences/_essence_text_view")
+ it "returns all ingredient view partial names for that element" do
+ is_expected.to include("alchemy/ingredients/_text_view")
end
end
@@ -50,7 +63,7 @@ module CacheDigests
context "with an element editor given as name" do
let(:name) { "alchemy/elements/_text_editor" }
- let(:elements) { [{"name" => "text", "contents" => [{"type" => "EssenceText"}]}] }
+ let(:elements) { [{ "name" => "text", "ingredients" => [{ "type" => "Text" }] }] }
it do
is_expected.to be_empty
@@ -59,13 +72,13 @@ module CacheDigests
context "with an element given as name" do
let(:name) { "alchemy/elements/_text" }
- let(:elements) { [{"name" => "text", "contents" => [{"type" => "EssenceText"}]}] }
+ let(:elements) { [{ "name" => "text", "ingredients" => [{ "type" => "Text" }] }] }
context "that is having a definition" do
before { allow(Element).to receive(:definitions).and_return(elements) }
- it "returns all essence layout view partial names for that element" do
- is_expected.to include("alchemy/essences/_essence_text_view")
+ it "returns all ingredient view partial names for that element" do
+ is_expected.to include("alchemy/ingredients/_text_view")
end
end
diff --git a/spec/libraries/tinymce_spec.rb b/spec/libraries/tinymce_spec.rb
index df5c38d05d..9e744d278f 100644
--- a/spec/libraries/tinymce_spec.rb
+++ b/spec/libraries/tinymce_spec.rb
@@ -21,10 +21,10 @@ module Alchemy
end
end
- context "Methods for contents with custom tinymce config." do
- let(:content_definition) do
+ context "Methods for ingredients with custom tinymce config." do
+ let(:ingredient_definition) do
{
- "name" => "text",
+ "role" => "text",
"settings" => {
"tinymce" => {
"foo" => "bar",
@@ -36,7 +36,7 @@ module Alchemy
let(:element_definition) do
{
"name" => "article",
- "contents" => [content_definition],
+ "ingredients" => [ingredient_definition],
}
end
@@ -45,113 +45,20 @@ module Alchemy
subject { described_class.custom_configs_present?(page) }
- context "if custom_config_contents are present" do
+ context "if custom_config_ingredients are present" do
before do
- expect(described_class).to receive(:custom_config_contents) { [:foo] }
+ expect(described_class).to receive(:custom_config_ingredients) { [:foo] }
end
it { is_expected.to be(true) }
end
- context "if no custom_config_contents are present" do
+ context "if no custom_config_ingredients are present" do
before do
- expect(described_class).to receive(:custom_config_contents) { [] }
+ expect(described_class).to receive(:custom_config_ingredients) { [] }
end
- context "but custom_config_ingredients are present" do
- before do
- expect(described_class).to receive(:custom_config_ingredients) { [:foo] }
- end
-
- it { is_expected.to be(true) }
- end
-
- context "and no custom_config_ingredients are present" do
- before do
- expect(described_class).to receive(:custom_config_ingredients) { [] }
- end
-
- it { is_expected.to be(false) }
- end
- end
- end
-
- describe ".custom_config_contents" do
- let(:page) { build_stubbed(:alchemy_page) }
-
- let(:element_definitions) do
- [element_definition]
- end
-
- subject { Tinymce.custom_config_contents(page) }
-
- before do
- expect(page).to receive(:descendent_element_definitions) { element_definitions }
- end
-
- it "returns an array of content definitions that contain custom tinymce config
- and element name" do
- is_expected.to be_an(Array)
- is_expected.to include({
- "element" => element_definition["name"],
- }.merge(content_definition))
- end
-
- context "with no contents having custom tinymce config" do
- let(:content_definition) do
- { "name" => "text" }
- end
-
- it { is_expected.to eq([]) }
- end
-
- context "with element definition having nil as contents value" do
- let(:element_definition) do
- {
- "name" => "element",
- "contents" => nil,
- }
- end
-
- it "returns empty array" do
- is_expected.to eq([])
- end
- end
-
- context "with content settings tinymce set to true only" do
- let(:element_definition) do
- {
- "name" => "element",
- "contents" => [
- "name" => "headline",
- "settings" => {
- "tinymce" => true,
- },
- ],
- }
- end
-
- it "returns empty array" do
- is_expected.to eq([])
- end
- end
-
- context "with nestable_elements defined" do
- let(:element_definitions) do
- [
- element_definition,
- {
- "name" => "nested_element",
- "contents" => [content_definition],
- },
- ]
- end
-
- it "includes these configs" do
- is_expected.to include({
- "element" => element_definition["name"],
- }.merge(content_definition))
- end
+ it { is_expected.to be(false) }
end
end
diff --git a/spec/models/alchemy/attachment_spec.rb b/spec/models/alchemy/attachment_spec.rb
index f8df895354..98273e4c2a 100644
--- a/spec/models/alchemy/attachment_spec.rb
+++ b/spec/models/alchemy/attachment_spec.rb
@@ -32,16 +32,15 @@ module Alchemy
end
end
- context "assigned to contents" do
+ context "assigned to ingredients" do
let(:attachment) { create(:alchemy_attachment) }
- let(:content) do
- create(:alchemy_content, :essence_file)
+ let(:ingredient) do
+ create(:alchemy_ingredient_file, related_object: attachment)
end
before do
- content.essence.update(attachment: attachment)
- content.element.update_column(:updated_at, 3.hours.ago)
+ ingredient.element.update_column(:updated_at, 3.hours.ago)
end
it "touches elements" do
diff --git a/spec/models/alchemy/content_spec.rb b/spec/models/alchemy/content_spec.rb
deleted file mode 100644
index 51bdd83048..0000000000
--- a/spec/models/alchemy/content_spec.rb
+++ /dev/null
@@ -1,533 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-module Alchemy
- describe Content do
- let(:element) { create(:alchemy_element, :with_contents, name: "headline") }
- let(:content) { element.contents.find_by(name: "headline") }
-
- it "should return the ingredient from its essence" do
- content.essence.update_columns(body: "Hello")
- expect(content.ingredient).to eq("Hello")
- end
-
- describe ".normalize_essence_type" do
- context "passing namespaced essence type" do
- it "should not add alchemy namespace" do
- expect(Content.normalize_essence_type("Alchemy::EssenceText")).to eq("Alchemy::EssenceText")
- end
- end
-
- context "passing not namespaced essence type" do
- it "should add alchemy namespace" do
- expect(Content.normalize_essence_type("EssenceText")).to eq("Alchemy::EssenceText")
- end
- end
-
- context "passing non-namespaced essence type for an existing non-namespaced essence" do
- it "should not add alchemy namespace" do
- expect(Content.normalize_essence_type("DummyModel")).to eq("DummyModel")
- end
- end
- end
-
- describe "#normalized_essence_type" do
- context "without namespace in essence_type column" do
- it "should return the namespaced essence type" do
- expect(Content.new(essence_type: "EssenceText").normalized_essence_type).to eq("Alchemy::EssenceText")
- end
- end
-
- context "with namespace in essence_type column" do
- it "should return the namespaced essence type" do
- expect(Content.new(essence_type: "Alchemy::EssenceText").normalized_essence_type).to eq("Alchemy::EssenceText")
- end
- end
- end
-
- describe "#update_essence" do
- subject { content.update_essence(params) }
-
- let(:element) { create(:alchemy_element, :with_contents, name: "text") }
- let(:content) { element.contents.first }
- let(:params) { {} }
-
- context "with params given" do
- let(:params) { { body: "Mikes Petshop" } }
- let(:essence) { content.essence }
-
- before do
- expect(essence).to receive(:content).at_least(:once).and_return content
- end
-
- it "updates the attributes of related essence and return true" do
- is_expected.to be_truthy
- expect(content.ingredient).to eq("Mikes Petshop")
- end
- end
-
- context "with validations and without params given" do
- let(:element) { create(:alchemy_element, :with_contents, name: "contactform") }
-
- it "should add error messages if save fails and return false" do
- is_expected.to be_falsey
- expect(content.errors[:essence].size).to eq(1)
- end
- end
-
- context "if essence is missing" do
- before do
- expect(content).to receive(:essence).and_return nil
- end
-
- it "should raise error" do
- expect { subject }.to raise_error(EssenceMissingError)
- end
- end
- end
-
- describe ".copy" do
- let(:element) do
- create(:alchemy_element, :with_contents, name: "text")
- end
-
- let(:new_element) do
- create(:alchemy_element, name: "text")
- end
-
- let(:content) do
- element.contents.first
- end
-
- it "should create a new record with all attributes of source except given differences" do
- copy = Content.copy(content, { element_id: new_element.id })
- expect(copy.element_id).to eq(new_element.id)
- end
-
- it "should make a new record for essence of source" do
- copy = Content.copy(content)
- expect(copy.essence_id).not_to eq(content.essence_id)
- end
-
- it "should copy source essence attributes" do
- content.essence.update_column(:body, "Lorem ipsum")
- copy = Content.copy(content)
- copy.essence.body == content.essence.body
- end
- end
-
- describe ".definitions" do
- context "without any definitions in elements.yml file" do
- before { expect(Element).to receive(:definitions).and_return([]) }
-
- it "should return an empty array" do
- expect(Content.definitions).to eq([])
- end
- end
-
- context "with some element definitions having no contents defined" do
- before do
- expect(Element).to receive(:definitions) do
- [
- {
- "name" => "foo",
- "contents" => [{ "name" => "title" }],
- },
- {
- "name" => "bar",
- },
- ]
- end
- end
-
- it "returns only content definitions" do
- expect(Content.definitions).to match_array(
- [{ "name" => "title" }],
- )
- end
- end
- end
-
- describe ".new" do
- let(:element) { build(:alchemy_element) }
-
- subject { Content.new({ element: element, name: "headline" }) }
-
- it "builds a new content instance from elements.yml definition" do
- is_expected.to be_instance_of(Content)
- is_expected.to_not be_persisted
- end
-
- it "builds a new essence instance from elements.yml definition" do
- expect(subject.essence).to be_instance_of(EssenceText)
- expect(subject.essence).to_not be_persisted
- end
-
- context "when given an essence_type attribute that is not in the definition" do
- let(:arguments) { { element: element, essence_type: "Alchemy::EssenceText", name: "not_in_elements_yml" } }
-
- subject { Content.new(arguments) }
-
- it "does not raise an error" do
- expect { subject }.not_to raise_exception
- expect(subject.name).to eq("not_in_elements_yml")
- expect(subject.essence).to be_a(Alchemy::EssenceText)
- end
- end
- end
-
- describe ".create" do
- let(:element) { create(:alchemy_element, name: "article") }
-
- subject(:content) { Content.create(element: element, name: "headline") }
-
- it "creates the content" do
- is_expected.to be_instance_of(Alchemy::Content)
- is_expected.to be_persisted
- end
-
- it "creates the essence" do
- expect(subject.essence).to be_instance_of(Alchemy::EssenceText)
- expect(subject.essence).to be_persisted
- end
-
- context "with default value present" do
- it "should have the ingredient column filled with default value." do
- allow_any_instance_of(Content).to receive(:definition) do
- {
- "name" => "headline",
- "type" => "EssenceText",
- "default" => "Welcome",
- }.with_indifferent_access
- end
- expect(content.ingredient).to eq("Welcome")
- end
-
- context "with default value being a symbol" do
- it "passes default value through I18n." do
- allow_any_instance_of(Content).to receive(:definition) do
- {
- "name" => "headline",
- "type" => "EssenceText",
- "default" => :welcome,
- }.with_indifferent_access
- end
- expect(content.ingredient).to eq("Welcome to my site")
- end
- end
- end
- end
-
- describe "#ingredient=" do
- let(:element) { create(:alchemy_element, name: "headline") }
-
- it "should set the given value to the ingredient column of essence" do
- c = Content.create(element: element, name: "headline")
- c.ingredient = "Welcome"
- expect(c.ingredient).to eq("Welcome")
- end
-
- context "no essence associated" do
- let(:element) { create(:alchemy_element, name: "headline") }
- let(:content) { Alchemy::Content.new(element: element, name: "headline").tap(&:save) }
-
- before do
- expect(content).to receive(:essence) { nil }
- end
-
- it "should raise error" do
- expect { content.ingredient = "Welcome" }.to raise_error(EssenceMissingError)
- end
- end
- end
-
- describe "#dom_id" do
- let(:content) { build_stubbed(:alchemy_content) }
-
- it "returns a dom id string" do
- expect(content.dom_id).to eq("essence_text_#{content.id}")
- end
-
- context "without an essence" do
- before { expect(content).to receive(:essence).and_return nil }
-
- it "returns empty string" do
- expect(content.dom_id).to eq("")
- end
- end
- end
-
- describe "#essence_partial_name" do
- let(:content) { build_stubbed(:alchemy_content) }
-
- it "returns the essence#partial_name" do
- expect(content.essence).to receive(:partial_name)
- content.essence_partial_name
- end
-
- context "without an essence" do
- before { expect(content).to receive(:essence).and_return nil }
-
- it "returns empty string" do
- expect(content.essence_partial_name).to eq("")
- end
- end
- end
-
- describe "#deprecated?" do
- let(:content) { build_stubbed(:alchemy_content) }
-
- subject { content.deprecated? }
-
- context "not defined as deprecated" do
- it "returns false" do
- expect(content.deprecated?).to be false
- end
- end
-
- context "defined as deprecated" do
- before do
- expect(content).to receive(:definition).at_least(:once).and_return({
- "deprecated" => true,
- })
- end
-
- it "returns true" do
- expect(content.deprecated?).to be true
- end
- end
-
- context "defined as deprecated per String" do
- before do
- expect(content).to receive(:definition).at_least(:once).and_return({
- "deprecated" => "This content is deprecated",
- })
- end
-
- it "returns true" do
- expect(content.deprecated?).to be true
- end
- end
- end
-
- describe "#preview_content?" do
- let(:content) { build_stubbed(:alchemy_content) }
-
- context "not defined as preview content" do
- it "returns false" do
- expect(content.preview_content?).to be false
- end
- end
-
- context "defined as preview content" do
- before do
- expect(content).to receive(:definition).at_least(:once).and_return({
- "as_element_title" => true,
- })
- end
-
- it "returns true" do
- expect(content.preview_content?).to be true
- end
- end
- end
-
- describe "#preview_text" do
- let(:essence) { mock_model(EssenceText, preview_text: "Lorem") }
- let(:content) { c = Content.new; c.essence = essence; c }
-
- it "should return the essences preview_text" do
- expect(essence).to receive(:preview_text).with(30)
- content.preview_text
- end
- end
-
- describe "#has_tinymce?" do
- let(:element) { build_stubbed(:alchemy_element, name: "article") }
- let(:content) { build_stubbed(:alchemy_content, name: "text", element: element) }
-
- subject { content.has_tinymce? }
-
- it { is_expected.to eq(false) }
-
- context "having custom tinymce config hash" do
- before do
- expect(content).to receive(:settings) do
- { tinymce: { toolbar: [] } }
- end
- end
-
- it { is_expected.to eq(true) }
- end
-
- context "having essence that has_tinymce? eq true" do
- before do
- expect(content.essence).to receive(:has_tinymce?) { true }
- end
-
- it { is_expected.to eq(true) }
- end
-
- context "having nil essence" do
- before do
- content.essence = nil
- end
-
- it { is_expected.to eq(false) }
- end
- end
-
- describe "#has_custom_tinymce_config?" do
- let(:element) { build_stubbed(:alchemy_element, name: "article") }
- let(:content) { build_stubbed(:alchemy_content, name: "text", element: element) }
-
- subject { content.has_custom_tinymce_config? }
-
- it { is_expected.to eq(false) }
-
- context "having custom tinymce config hash" do
- before do
- expect(content).to receive(:settings) do
- { tinymce: { toolbar: [] } }
- end
- end
-
- it { is_expected.to eq(true) }
- end
- end
-
- describe "#tinymce_class_name" do
- let(:element) { build_stubbed(:alchemy_element, name: "article") }
- let(:content) { build_stubbed(:alchemy_content, name: "text", element: element) }
-
- subject { content.tinymce_class_name }
-
- it { is_expected.to eq("has_tinymce") }
-
- context "having custom tinymce config" do
- before do
- expect(content).to receive(:has_custom_tinymce_config?).and_return(true)
- end
-
- it "returns name including element name" do
- is_expected.to eq("has_tinymce article_text")
- end
- end
- end
-
- it_behaves_like "having a hint" do
- let(:subject) { Content.new }
- end
-
- describe "#settings" do
- let(:element) { build_stubbed(:alchemy_element, name: "article") }
- let(:content) { build_stubbed(:alchemy_content, name: "headline", element: element) }
-
- it "returns the settings hash from definition" do
- expect(content.settings).to eq({ "linkable" => true })
- end
-
- context "if settings are not defined" do
- let(:content) { build_stubbed(:alchemy_content, name: "intro", element: element) }
-
- it "returns empty hash" do
- expect(content.settings).to eq({})
- end
- end
- end
-
- describe "#settings_value" do
- let(:key) { :key }
- let(:settings) { Hash.new }
-
- subject { content.settings_value(key, options) }
-
- before do
- allow(content).to receive(:settings) { settings }
- end
-
- context "with content having settings" do
- let(:settings) { { key: "settings_value" } }
-
- context "and empty options" do
- let(:options) { {} }
-
- it "returns the value for key from content settings" do
- expect(subject).to eq("settings_value")
- end
- end
-
- context "and nil options" do
- let(:options) { nil }
-
- it "returns the value for key from content settings" do
- expect(subject).to eq("settings_value")
- end
- end
-
- context "but same key present in options" do
- let(:options) { { key: "options_value" } }
-
- it "returns the value for key from options" do
- expect(subject).to eq("options_value")
- end
- end
- end
-
- context "with content having no settings" do
- let(:settings) { {} }
-
- context "and empty options" do
- let(:options) { {} }
-
- it { expect(subject).to eq(nil) }
- end
-
- context "but key present in options" do
- let(:options) { { key: "options_value" } }
-
- it "returns the value for key from options" do
- expect(subject).to eq("options_value")
- end
- end
- end
-
- context "with content having settings with string as key" do
- let(:settings) { { "key" => "value_from_string_key" } }
- let(:options) { {} }
-
- it "returns value" do
- expect(subject).to eq("value_from_string_key")
- end
- end
-
- context "with key passed as string" do
- let(:settings) { { key: "value_from_symbol_key" } }
- let(:key) { "key" }
- let(:options) { {} }
-
- it "returns value" do
- expect(subject).to eq("value_from_symbol_key")
- end
- end
- end
-
- context "delegations" do
- let(:page) { create(:alchemy_page, :restricted) }
-
- it "delegates restricted? to page" do
- element.update!(page: page)
- expect(page.restricted?).to be true
- expect(content.page).to eq page
- expect(content.restricted?).to be true
- end
-
- it "delegates public? to element" do
- element.update!(public: false)
- expect(element.public?).to be false
- expect(content.public?).to be false
- end
- end
- end
-end
diff --git a/spec/models/alchemy/eager_loading_spec.rb b/spec/models/alchemy/eager_loading_spec.rb
index e8c52fed3b..c73c951a7e 100644
--- a/spec/models/alchemy/eager_loading_spec.rb
+++ b/spec/models/alchemy/eager_loading_spec.rb
@@ -19,7 +19,6 @@
:tags,
{
ingredients: :related_object,
- contents: :essence,
},
],
},
@@ -43,7 +42,6 @@
:tags,
{
ingredients: :related_object,
- contents: :essence,
},
],
},
diff --git a/spec/models/alchemy/element_ingredients_spec.rb b/spec/models/alchemy/element_ingredients_spec.rb
index b4cb940092..90d6d20e4a 100644
--- a/spec/models/alchemy/element_ingredients_spec.rb
+++ b/spec/models/alchemy/element_ingredients_spec.rb
@@ -10,42 +10,46 @@
it "creates ingredients after creation" do
expect {
element.save!
- }.to change { element.ingredients.count }.by(2)
+ }.to change { element.ingredients.count }.by(4)
end
describe "#ingredients_by_type" do
let(:element) { create(:alchemy_element, :with_ingredients) }
let(:expected_ingredients) { element.ingredients.texts }
- context "with namespaced essence type" do
+ context "with namespaced type" do
subject { element.ingredients_by_type("Alchemy::Text") }
it { is_expected.not_to be_empty }
- it("should return the correct list of essences") { is_expected.to eq(expected_ingredients) }
+ it "should return the correct list of ingredients" do
+ is_expected.to eq(expected_ingredients)
+ end
end
- context "without namespaced essence type" do
+ context "without namespaced type" do
subject { element.ingredients_by_type("Text") }
it { is_expected.not_to be_empty }
- it("should return the correct list of essences") { is_expected.to eq(expected_ingredients) }
+ it "should return the correct list of ingredients" do
+ is_expected.to eq(expected_ingredients)
+ end
end
end
describe "#ingredient_by_type" do
let!(:element) { create(:alchemy_element, :with_ingredients) }
- let(:ingredient) { element.ingredients.first }
+ let(:ingredient) { element.ingredients.find_by!(type: "Alchemy::Ingredients::Text") }
- context "with namespaced essence type" do
- it "should return ingredient by passing a essence type" do
- expect(element.ingredient_by_type("Alchemy::Text")).to eq(ingredient)
+ context "with namespaced type" do
+ it "should return ingredient by passing a type" do
+ expect(element.ingredient_by_type("Alchemy::Ingredients::Text")).to eq(ingredient)
end
end
- context "without namespaced essence type" do
- it "should return ingredient by passing a essence type" do
+ context "without namespaced type" do
+ it "should return ingredient by passing a type" do
expect(element.ingredient_by_type("Text")).to eq(ingredient)
end
end
@@ -53,7 +57,7 @@
describe "#ingredient_by_role" do
let!(:element) { create(:alchemy_element, :with_ingredients) }
- let(:ingredient) { element.ingredients.first }
+ let(:ingredient) { element.ingredients.find_by!(role: "headline") }
context "with role existing" do
it "should return ingredient" do
@@ -98,7 +102,7 @@
describe "#has_value_for?" do
let!(:element) do
- create(:alchemy_element, :with_ingredients, name: "all_you_can_eat_ingredients")
+ create(:alchemy_element, :with_ingredients, name: "all_you_can_eat")
end
context "with role existing" do
@@ -125,7 +129,7 @@
end
describe "ingredient validations" do
- let(:element) { create(:alchemy_element, :with_ingredients, name: "all_you_can_eat_ingredients") }
+ let(:element) { create(:alchemy_element, :with_ingredients, name: "all_you_can_eat") }
before do
element.update(
@@ -144,7 +148,7 @@
end
describe "#ingredient_error_messages" do
- let(:element) { create(:alchemy_element, :with_ingredients, name: "all_you_can_eat_ingredients") }
+ let(:element) { create(:alchemy_element, :with_ingredients, name: "all_you_can_eat") }
before do
element.update(
@@ -164,4 +168,50 @@
])
end
end
+
+ describe "#richtext_ingredients_ids" do
+ subject { element.richtext_ingredients_ids }
+
+ let(:element) { create(:alchemy_element, :with_ingredients, name: "text") }
+
+ it { is_expected.to eq(element.ingredient_ids) }
+
+ context "for element with nested elements" do
+ let!(:element) do
+ create(:alchemy_element, :with_ingredients, name: "text")
+ end
+
+ let!(:nested_element_1) do
+ create(:alchemy_element, :with_ingredients, {
+ name: "text",
+ parent_element: element,
+ folded: false,
+ })
+ end
+
+ let!(:nested_element_2) do
+ create(:alchemy_element, :with_ingredients, {
+ name: "text",
+ parent_element: nested_element_1,
+ folded: false,
+ })
+ end
+
+ let!(:folded_nested_element_3) do
+ create(:alchemy_element, :with_ingredients, {
+ name: "text",
+ parent_element: nested_element_1,
+ folded: true,
+ })
+ end
+
+ it "includes all richtext ingredients from all expanded descendent elements" do
+ is_expected.to eq(
+ element.ingredient_ids +
+ nested_element_1.ingredient_ids +
+ nested_element_2.ingredient_ids,
+ )
+ end
+ end
+ end
end
diff --git a/spec/models/alchemy/element_spec.rb b/spec/models/alchemy/element_spec.rb
index cd5398e677..8d854eb761 100644
--- a/spec/models/alchemy/element_spec.rb
+++ b/spec/models/alchemy/element_spec.rb
@@ -31,7 +31,7 @@ module Alchemy
it "should not have forbidden attributes from definition" do
el = Element.new(name: "article")
- expect(el.contents).to eq([])
+ expect(el.ingredients).to eq([])
end
end
@@ -39,55 +39,20 @@ module Alchemy
let(:page_version) { build(:alchemy_page_version) }
subject(:element) do
- described_class.create(page_version: page_version, name: "article", autogenerate_contents: true)
+ described_class.create(page_version: page_version, name: "article", autogenerate_ingredients: true)
end
- it "creates contents" do
- expect(element.contents).to match_array([
- an_instance_of(Alchemy::Content),
- an_instance_of(Alchemy::Content),
- an_instance_of(Alchemy::Content),
- an_instance_of(Alchemy::Content),
- ])
- end
-
- context "if autogenerate_contents set to false" do
+ context "if autogenerate_ingredients set to false" do
subject(:element) do
described_class.create(
page_version: page_version,
name: "article",
- autogenerate_contents: false,
+ autogenerate_ingredients: false,
)
end
- it "does not create contents" do
- expect(element.contents).to be_empty
- end
- end
-
- context "if ingredients are defined as well" do
- before do
- expect_any_instance_of(Alchemy::Element).to receive(:definition).at_least(:once) do
- {
- name: "article",
- contents: [
- {
- name: "headline",
- type: "EssenceText",
- },
- ],
- ingredients: [
- {
- role: "headline",
- type: "Text",
- },
- ],
- }.with_indifferent_access
- end
- end
-
- it "does not create contents" do
- expect(element.contents).to be_empty
+ it "does not create ingredients" do
+ expect(element.ingredients).to be_empty
end
end
@@ -144,8 +109,8 @@ module Alchemy
)
end
- it "creates contents" do
- expect(element.contents).to be_empty
+ it "does not create ingredients" do
+ expect(element.ingredients).to be_empty
end
end
end
@@ -176,11 +141,11 @@ module Alchemy
subject { Element.copy(element) }
let(:element) do
- create(:alchemy_element, :with_contents, tag_list: "red, yellow")
+ create(:alchemy_element, :with_ingredients, tag_list: "red, yellow")
end
- it "should not create contents from scratch" do
- expect(subject.contents.count).to eq(element.contents.count)
+ it "should not create ingredients from scratch" do
+ expect(subject.ingredients.count).to eq(element.ingredients.count)
end
context "with differences" do
@@ -192,9 +157,9 @@ module Alchemy
end
end
- it "should make copies of all contents of source" do
- expect(subject.contents).not_to be_empty
- expect(subject.contents.pluck(:id)).not_to eq(element.contents.pluck(:id))
+ it "should make copies of all ingredients of source" do
+ expect(subject.ingredients).not_to be_empty
+ expect(subject.ingredients.pluck(:id)).not_to eq(element.ingredients.pluck(:id))
end
it "the copy should include source element tags" do
@@ -203,7 +168,7 @@ module Alchemy
context "with nested elements" do
let(:element) do
- create(:alchemy_element, :with_contents, :with_nestable_elements, {
+ create(:alchemy_element, :with_ingredients, :with_nestable_elements, {
tag_list: "red, yellow",
page: create(:alchemy_page),
})
@@ -477,42 +442,6 @@ module Alchemy
# InstanceMethods
- describe "#all_contents_by_type" do
- let(:element) { create(:alchemy_element, :with_contents) }
- let(:expected_contents) { element.contents.essence_texts }
-
- context "with namespaced essence type" do
- subject { element.all_contents_by_type("Alchemy::EssenceText") }
- it { is_expected.not_to be_empty }
- it("should return the correct list of essences") { is_expected.to eq(expected_contents) }
- end
-
- context "without namespaced essence type" do
- subject { element.all_contents_by_type("EssenceText") }
- it { is_expected.not_to be_empty }
- it("should return the correct list of essences") { is_expected.to eq(expected_contents) }
- end
- end
-
- describe "#content_by_type" do
- before(:each) do
- @element = create(:alchemy_element, name: "headline")
- @content = @element.contents.first
- end
-
- context "with namespaced essence type" do
- it "should return content by passing a essence type" do
- expect(@element.content_by_type("Alchemy::EssenceText")).to eq(@content)
- end
- end
-
- context "without namespaced essence type" do
- it "should return content by passing a essence type" do
- expect(@element.content_by_type("EssenceText")).to eq(@content)
- end
- end
- end
-
describe "#display_name" do
let(:element) { Element.new(name: "article") }
@@ -522,46 +451,6 @@ module Alchemy
end
end
- describe "#essence_errors" do
- let(:element) { Element.new(name: "article") }
- let(:content) { Content.new(name: "headline") }
- let(:essence) { EssenceText.new(body: "") }
-
- before do
- allow(element).to receive(:contents) { [content] }
- allow(content).to receive(:essence) { essence }
- allow(content).to receive(:essence_validation_failed?) { true }
- allow(essence).to receive(:validation_errors) { "Cannot be blank" }
- end
-
- it "returns hash with essence errors" do
- expect(element.essence_errors).to eq({ "headline" => "Cannot be blank" })
- end
- end
-
- describe "#essence_error_messages" do
- let(:element) { Element.new(name: "article") }
-
- it "should return the translation with the translated content label" do
- expect(Alchemy).to receive(:t)
- .with("content_names.content", default: "Content")
- .and_return("Content")
- expect(Alchemy).to receive(:t)
- .with("content", scope: "content_names.article", default: "Content")
- .and_return("Contenido")
- expect(Alchemy).to receive(:t)
- .with("article.content.invalid", {
- scope: "content_validations",
- default: [:"fields.content.invalid", :"errors.invalid"],
- field: "Contenido",
- })
- expect(element).to receive(:essence_errors)
- .and_return({ "content" => [:invalid] })
-
- element.essence_error_messages
- end
- end
-
describe "#display_name_with_preview_text" do
let(:element) { build_stubbed(:alchemy_element, name: "Foo") }
@@ -591,7 +480,7 @@ module Alchemy
end
let(:ingredient_2) do
- mock_model(Ingredients::Text, role: "headline", preview_text: "Ingredient 2", preview_ingredient?: false)
+ mock_model(Ingredients::Text, role: "intro", preview_text: "Ingredient 2", preview_ingredient?: false)
end
let(:ingredients) { [] }
@@ -629,65 +518,8 @@ module Alchemy
end
end
- context "with element having contents" do
- let(:content) do
- mock_model(Content, preview_text: "Content 1", preview_content?: false)
- end
-
- let(:content_2) do
- mock_model(Content, preview_text: "Content 2", preview_content?: false)
- end
-
- let(:contents) { [] }
-
- let(:preview_content) do
- mock_model(Content, preview_text: "Preview Content", preview_content?: true)
- end
-
- before do
- allow(element).to receive(:contents).and_return(contents)
- end
-
- context "without a content marked as preview" do
- let(:contents) { [content, content_2] }
-
- it "returns the preview text of first content found" do
- expect(content).to receive(:preview_text).with(60)
- element.preview_text
- end
- end
-
- context "with a content marked as preview" do
- let(:contents) { [content, preview_content] }
-
- it "should return the preview_text of this content" do
- expect(preview_content).to receive(:preview_text).with(60)
- element.preview_text
- end
- end
-
- context "without any contents present" do
- it "should return nil" do
- expect(element.preview_text).to be_nil
- end
- end
- end
-
context "with nested elements" do
- let(:element) do
- build_stubbed(:alchemy_element, :with_nestable_elements)
- end
-
- let(:nested_element) do
- build_stubbed(:alchemy_element, name: "slide")
- end
-
- let(:content_2) do
- mock_model(Content, preview_text: "Content 2", preview_content?: false)
- end
-
before do
- allow(nested_element).to receive(:contents) { [content_2] }
allow(element).to receive(:all_nested_elements) { [nested_element] }
end
@@ -699,7 +531,7 @@ module Alchemy
end
let(:ingredient) do
- mock_model(Ingredients::Text, role: "headline", preview_text: "Ingredient 1", preview_ingredient?: false)
+ mock_model(Ingredients::Text, element: element, role: "intro", preview_text: "Ingredient 1", preview_ingredient?: false)
end
before do
@@ -717,7 +549,7 @@ module Alchemy
let(:nested_element) { build_stubbed(:alchemy_element, :with_ingredients) }
let(:ingredient) do
- mock_model(Ingredients::Text, role: "headline", preview_text: "Ingredient 1", preview_ingredient?: false)
+ mock_model(Ingredients::Text, role: "intro", preview_text: "Ingredient 1", preview_ingredient?: false)
end
before do
@@ -730,37 +562,6 @@ module Alchemy
expect(element.preview_text)
end
end
-
- context "when parent element has contents" do
- let(:content) do
- mock_model(Content, preview_text: "Content 1", preview_content?: false)
- end
-
- before do
- allow(element).to receive(:contents) { [content] }
- end
-
- it "returns the preview text from the parent element" do
- expect(content).to receive(:preview_text)
- expect(element.preview_text)
- end
- end
-
- context "when parent element has no contents but nestable element has" do
- let(:content) do
- mock_model(Content, preview_text: "Content 1", preview_content?: false)
- end
-
- before do
- allow(element).to receive(:contents) { [] }
- allow(nested_element).to receive(:contents) { [content] }
- end
-
- it "returns the preview text from the first nested element" do
- expect(content).to receive(:preview_text)
- expect(element.preview_text)
- end
- end
end
end
@@ -798,85 +599,6 @@ module Alchemy
end
end
- context "retrieving contents, essences and ingredients" do
- let(:element) { create(:alchemy_element, :with_contents, name: "news") }
-
- describe "#ingredient" do
- context "with contents" do
- let(:essence) { element.content_by_name(:news_headline) }
-
- it "returns a contents value by name" do
- expect(essence).to receive(:ingredient).and_call_original
- element.ingredient("news_headline")
- end
- end
-
- context "with ingredients" do
- let(:element) { create(:alchemy_element, :with_ingredients) }
- let(:ingredient) { element.ingredient_by_role(:headline) }
-
- it "returns a ingredients value by name" do
- Alchemy::Deprecation.silenced do
- expect(ingredient).to receive(:value).and_call_original
- element.ingredient("headline")
- end
- end
- end
- end
- end
-
- describe "#update_contents" do
- subject { element.update_contents(params) }
-
- let(:element) { build_stubbed(:alchemy_element) }
- let(:content1) { double(:content, id: 1) }
- let(:content2) { double(:content, id: 2) }
-
- before { allow(element).to receive(:contents).and_return([content1]) }
-
- context "with attributes hash is nil" do
- let(:params) { nil }
- it { is_expected.to be_truthy }
- end
-
- context "with valid attributes hash" do
- let(:params) { { content1.id.to_s => { body: "Title" } } }
-
- context "when certain content is not part of the attributes hash (cause it was not filled by the user)" do
- before do
- allow(element).to receive(:contents).and_return([content1, content2])
- end
-
- it "does not try to update that content" do
- expect(content1).to receive(:update_essence).with({ body: "Title" }).and_return(true)
- expect(content2).to_not receive(:update_essence)
- subject
- end
- end
-
- context "with passing validations" do
- before do
- expect(content1).to receive(:update_essence).with({ body: "Title" }).and_return(true)
- end
-
- it { is_expected.to be_truthy }
-
- it "does not add errors" do
- subject
- expect(element.errors).to be_empty
- end
- end
-
- context "with failing validations" do
- it "adds error and returns false" do
- expect(content1).to receive(:update_essence).with({ body: "Title" }).and_return(false)
- is_expected.to be_falsey
- expect(element.errors).not_to be_empty
- end
- end
- end
- end
-
describe ".after_update" do
let(:element) { create(:alchemy_element, page_version: page_version) }
@@ -1076,52 +798,6 @@ module Alchemy
end
end
- describe "#richtext_contents_ids" do
- subject { element.richtext_contents_ids }
-
- let(:element) { create(:alchemy_element, :with_contents, name: "text") }
-
- it { is_expected.to eq(element.content_ids) }
-
- context "for element with nested elements" do
- let!(:element) do
- create(:alchemy_element, :with_contents, name: "text")
- end
-
- let!(:nested_element_1) do
- create(:alchemy_element, :with_contents, {
- name: "text",
- parent_element: element,
- folded: false,
- })
- end
-
- let!(:nested_element_2) do
- create(:alchemy_element, :with_contents, {
- name: "text",
- parent_element: nested_element_1,
- folded: false,
- })
- end
-
- let!(:folded_nested_element_3) do
- create(:alchemy_element, :with_contents, {
- name: "text",
- parent_element: nested_element_1,
- folded: true,
- })
- end
-
- it "includes all richtext contents from all expanded descendent elements" do
- is_expected.to eq(
- element.content_ids +
- nested_element_1.content_ids +
- nested_element_2.content_ids,
- )
- end
- end
- end
-
context "with parent element" do
let!(:parent_element) { create(:alchemy_element, :with_nestable_elements) }
let!(:element) { create(:alchemy_element, name: "slide", parent_element: parent_element) }
diff --git a/spec/models/alchemy/essence_audio_spec.rb b/spec/models/alchemy/essence_audio_spec.rb
deleted file mode 100644
index a8082996b8..0000000000
--- a/spec/models/alchemy/essence_audio_spec.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-RSpec.describe Alchemy::EssenceAudio do
- let(:attachment) { create(:alchemy_attachment) }
- let(:essence) { described_class.new(attachment: attachment) }
-
- it_behaves_like "an essence" do
- let(:ingredient_value) { attachment }
- end
-end
diff --git a/spec/models/alchemy/essence_boolean_spec.rb b/spec/models/alchemy/essence_boolean_spec.rb
deleted file mode 100644
index 239796e59f..0000000000
--- a/spec/models/alchemy/essence_boolean_spec.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-module Alchemy
- describe EssenceBoolean do
- it_behaves_like "an essence" do
- let(:essence) { EssenceBoolean.new }
- let(:ingredient_value) { true }
- end
- end
-end
diff --git a/spec/models/alchemy/essence_date_spec.rb b/spec/models/alchemy/essence_date_spec.rb
deleted file mode 100644
index 7aaa8eb442..0000000000
--- a/spec/models/alchemy/essence_date_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-module Alchemy
- describe EssenceDate do
- let(:essence) { EssenceDate.new }
-
- it_behaves_like "an essence" do
- let(:essence) { EssenceDate.new }
- let(:ingredient_value) { Time.current.iso8601 }
- end
-
- describe "#preview_text" do
- subject { essence.preview_text }
-
- context "if no date set" do
- it "should return an empty string" do
- is_expected.to eq("")
- end
- end
-
- context "if date set" do
- it "should format the date by i18n" do
- essence.date = Time.current
- expect(::I18n).to receive(:l).with(essence.date, format: :'alchemy.essence_date')
- subject
- end
- end
- end
- end
-end
diff --git a/spec/models/alchemy/essence_file_spec.rb b/spec/models/alchemy/essence_file_spec.rb
deleted file mode 100644
index 249901955f..0000000000
--- a/spec/models/alchemy/essence_file_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-module Alchemy
- describe EssenceFile do
- let(:attachment) { create(:alchemy_attachment) }
- let(:essence) { EssenceFile.new(attachment: attachment) }
-
- it_behaves_like "an essence" do
- let(:essence) { EssenceFile.new }
- let(:ingredient_value) { attachment }
- end
-
- describe "#attachment_url" do
- subject { essence.attachment_url }
-
- it "returns the download attachment url." do
- is_expected.to match(/\/attachment\/#{attachment.id}\/download\/#{attachment.slug}\.#{attachment.suffix}/)
- end
-
- context "without attachment assigned" do
- let(:attachment) { nil }
-
- it { is_expected.to be_nil }
- end
- end
-
- describe "#preview_text" do
- it "returns the attachment's name as preview text" do
- expect(essence.preview_text).to eq(attachment.name)
- end
-
- context "with no attachment assigned" do
- it "returns empty string" do
- essence.attachment = nil
- expect(essence.preview_text).to eq("")
- end
- end
- end
- end
-end
diff --git a/spec/models/alchemy/essence_headline_spec.rb b/spec/models/alchemy/essence_headline_spec.rb
deleted file mode 100644
index c924330cee..0000000000
--- a/spec/models/alchemy/essence_headline_spec.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-RSpec.describe Alchemy::EssenceHeadline do
- subject(:essence) do
- Alchemy::EssenceHeadline.new(
- body: ingredient_value,
- level: 2,
- size: 3
- )
- end
-
- let(:ingredient_value) { "A headline" }
-
- it_behaves_like "an essence"
-
- describe "#level_options" do
- subject { essence.level_options }
-
- it { is_expected.to eq([["H1", 1], ["H2", 2], ["H3", 3], ["H4", 4], ["H5", 5], ["H6", 6]]) }
-
- context "when restricted through the essence settings" do
- before do
- expect(essence).to receive_message_chain(:content, :settings).and_return(levels: [2, 3])
- end
-
- it { is_expected.to eq([["H2", 2], ["H3", 3]]) }
- end
- end
-
- describe "#size_options" do
- subject { essence.size_options }
-
- it { is_expected.to eq([]) }
-
- context "when enabled through the essence settings" do
- before do
- expect(essence).to receive_message_chain(:content, :settings).and_return(sizes: [3, 4])
- end
-
- it { is_expected.to eq([["H3", 3], ["H4", 4]]) }
- end
- end
-
- describe "initialization" do
- describe "level" do
- subject { Alchemy::EssenceHeadline.new.level }
-
- it { is_expected.to eq(1) }
- end
-
- describe "size" do
- let(:content) { build(:alchemy_content) }
- let(:essence) { Alchemy::EssenceHeadline.new(content: content) }
- subject { essence.size }
-
- it { is_expected.to be_nil }
-
- context "when enabled through the essence settings" do
- before do
- expect(content).to receive(:settings).and_return(sizes: [3, 4]).twice
- end
-
- it { is_expected.to eq(3) }
- end
- end
- end
-
- describe "creating from a content" do
- it "should have the size and level fields filled with correct defaults" do
- element = create(:alchemy_element)
-
- allow(element).to receive(:content_definition_for) do
- {
- "name" => "headline",
- "type" => "EssenceHeadline",
- "settings" => {
- "sizes" => [3],
- "levels" => [2, 3],
- },
- }.with_indifferent_access
- end
-
- content = Alchemy::Content.create(element: element, name: "headline")
- expect(content.essence.size).to eq(3)
- expect(content.essence.level).to eq(2)
- end
- end
-end
diff --git a/spec/models/alchemy/essence_html_spec.rb b/spec/models/alchemy/essence_html_spec.rb
deleted file mode 100644
index fd4b0c7494..0000000000
--- a/spec/models/alchemy/essence_html_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-# frozen_string_literal: true
-
-require "rails_helper"
-
-module Alchemy
- describe EssenceHtml do
- let(:essence) { EssenceHtml.new(source: "