alchemy_cms 8.0.7 → 8.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -10
- data/app/assets/builds/alchemy/admin.css +1 -1
- data/app/assets/builds/alchemy/dark-theme.css +1 -1
- data/app/assets/builds/alchemy/light-theme.css +1 -1
- data/app/assets/builds/alchemy/preview.min.js +1 -1
- data/app/assets/builds/alchemy/theme.css +1 -1
- data/app/{views/alchemy/admin/elements/_element.html.erb → components/alchemy/admin/element_editor.html.erb} +34 -29
- data/app/components/alchemy/admin/element_editor.rb +115 -0
- data/app/components/alchemy/admin/element_select.rb +12 -9
- data/app/components/alchemy/admin/ingredient_editor.rb +54 -0
- data/app/components/alchemy/admin/list_filter.rb +16 -5
- data/app/components/alchemy/admin/page_node.html.erb +215 -0
- data/app/components/alchemy/admin/page_node.rb +70 -0
- data/app/components/alchemy/admin/picture_thumbnail.rb +36 -0
- data/app/components/alchemy/admin/publish_page_button.html.erb +15 -0
- data/app/components/alchemy/admin/publish_page_button.rb +54 -0
- data/app/{helpers/alchemy/admin/tags_helper.rb → components/alchemy/admin/tags_list.rb} +19 -11
- data/app/components/alchemy/admin/toolbar_button.rb +16 -12
- data/app/components/alchemy/ingredients/audio_editor.rb +8 -0
- data/app/components/alchemy/ingredients/base_editor.rb +222 -0
- data/app/components/alchemy/ingredients/boolean_editor.rb +21 -0
- data/app/components/alchemy/ingredients/color_editor.rb +80 -0
- data/app/components/alchemy/ingredients/color_view.rb +13 -0
- data/app/components/alchemy/ingredients/datetime_editor.rb +28 -0
- data/app/components/alchemy/ingredients/file_editor.rb +69 -0
- data/app/components/alchemy/ingredients/headline_editor.rb +88 -0
- data/app/components/alchemy/ingredients/html_editor.rb +11 -0
- data/app/components/alchemy/ingredients/link_editor.rb +29 -0
- data/app/components/alchemy/ingredients/node_editor.rb +23 -0
- data/app/components/alchemy/ingredients/number_editor.rb +28 -0
- data/app/components/alchemy/ingredients/page_editor.rb +19 -0
- data/app/components/alchemy/ingredients/picture_editor.rb +81 -0
- data/app/components/alchemy/ingredients/richtext_editor.rb +31 -0
- data/app/components/alchemy/ingredients/select_editor.rb +37 -0
- data/app/components/alchemy/ingredients/select_view.rb +7 -0
- data/app/components/alchemy/ingredients/text_editor.rb +41 -0
- data/app/components/alchemy/ingredients/video_editor.rb +8 -0
- data/app/controllers/alchemy/admin/attachments_controller.rb +8 -6
- data/app/controllers/alchemy/admin/base_controller.rb +7 -18
- data/app/controllers/alchemy/admin/clipboard_controller.rb +15 -11
- data/app/controllers/alchemy/admin/dashboard_controller.rb +2 -2
- data/app/controllers/alchemy/admin/elements_controller.rb +34 -32
- data/app/controllers/alchemy/admin/ingredients_controller.rb +1 -0
- data/app/controllers/alchemy/admin/layoutpages_controller.rb +2 -1
- data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +1 -1
- data/app/controllers/alchemy/admin/nodes_controller.rb +24 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +31 -41
- data/app/controllers/alchemy/admin/pictures_controller.rb +2 -5
- data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
- data/app/controllers/alchemy/api/ingredients_controller.rb +1 -1
- data/app/controllers/alchemy/api/pages_controller.rb +5 -3
- data/app/controllers/alchemy/base_controller.rb +6 -6
- data/app/controllers/alchemy/pages_controller.rb +12 -6
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +0 -1
- data/app/controllers/concerns/alchemy/admin/clipboard.rb +57 -0
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +2 -2
- data/app/controllers/concerns/alchemy/site_redirects.rb +1 -1
- data/app/decorators/alchemy/ingredient_editor.rb +37 -4
- data/app/helpers/alchemy/admin/base_helper.rb +10 -6
- data/app/helpers/alchemy/admin/ingredients_helper.rb +6 -3
- data/app/helpers/alchemy/base_helper.rb +1 -1
- data/app/helpers/alchemy/pages_helper.rb +1 -1
- data/app/javascript/alchemy_admin/components/action.js +5 -1
- data/app/javascript/alchemy_admin/components/color_select.js +73 -0
- data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +11 -3
- data/app/javascript/alchemy_admin/components/element_editor/publish_element_button.js +7 -2
- data/app/javascript/alchemy_admin/components/element_editor.js +11 -12
- data/app/javascript/alchemy_admin/components/element_select.js +39 -17
- data/app/javascript/alchemy_admin/components/elements_window.js +0 -2
- data/app/javascript/alchemy_admin/components/file_editor.js +26 -0
- data/app/javascript/alchemy_admin/components/index.js +9 -0
- data/app/javascript/alchemy_admin/components/list_filter.js +57 -8
- data/app/javascript/alchemy_admin/components/message.js +9 -3
- data/app/javascript/alchemy_admin/components/page_node.js +119 -0
- data/app/javascript/alchemy_admin/{page_publication_fields.js → components/page_publication_fields.js} +9 -8
- data/app/javascript/alchemy_admin/{picture_editors.js → components/picture_editor.js} +30 -45
- data/app/javascript/alchemy_admin/components/picture_thumbnail.js +107 -0
- data/app/javascript/alchemy_admin/components/publish_page_button.js +41 -0
- data/app/javascript/alchemy_admin/components/select.js +3 -1
- data/app/javascript/alchemy_admin/components/sitemap.js +210 -0
- data/app/javascript/alchemy_admin/{sortable_elements.js → components/sortable_elements.js} +22 -25
- data/app/javascript/alchemy_admin/components/tinymce.js +10 -5
- data/app/javascript/alchemy_admin/components/update_check.js +1 -1
- data/app/javascript/alchemy_admin/components/uploader.js +30 -0
- data/app/javascript/alchemy_admin/image_overlay.js +0 -2
- data/app/javascript/alchemy_admin/initializer.js +0 -3
- data/app/javascript/alchemy_admin/templates/compiled.js +1 -1
- data/app/javascript/alchemy_admin/utils/ajax.js +15 -3
- data/app/javascript/alchemy_admin.js +0 -6
- data/app/models/alchemy/attachment.rb +4 -4
- data/app/models/alchemy/element/definitions.rb +1 -2
- data/app/models/alchemy/element/element_ingredients.rb +6 -2
- data/app/models/alchemy/element.rb +54 -13
- data/app/models/alchemy/element_definition.rb +4 -1
- data/app/models/alchemy/elements_repository.rb +6 -0
- data/app/models/alchemy/folded_page.rb +2 -2
- data/app/models/alchemy/ingredient.rb +38 -1
- data/app/models/alchemy/ingredient_definition.rb +4 -1
- data/app/models/alchemy/ingredient_validator.rb +6 -2
- data/app/models/alchemy/ingredients/color.rb +10 -0
- data/app/models/alchemy/ingredients/headline.rb +2 -17
- data/app/models/alchemy/ingredients/picture.rb +4 -4
- data/app/models/alchemy/ingredients/select.rb +19 -0
- data/app/models/alchemy/node.rb +28 -1
- data/app/models/alchemy/page/page_naming.rb +0 -7
- data/app/models/alchemy/page/page_natures.rb +7 -3
- data/app/models/alchemy/page/page_scopes.rb +1 -1
- data/app/models/alchemy/page/publisher.rb +14 -2
- data/app/models/alchemy/page.rb +102 -23
- data/app/models/alchemy/page_definition.rb +4 -1
- data/app/models/alchemy/page_version.rb +22 -6
- data/app/models/alchemy/picture.rb +10 -11
- data/app/models/alchemy/picture_variant.rb +1 -3
- data/app/models/alchemy/resource.rb +1 -1
- data/app/models/alchemy/storage_adapter/active_storage.rb +14 -2
- data/app/models/alchemy/storage_adapter/dragonfly.rb +12 -0
- data/app/models/alchemy/storage_adapter.rb +2 -0
- data/app/models/concerns/alchemy/picture_thumbnails.rb +4 -4
- data/app/models/concerns/alchemy/publishable.rb +54 -0
- data/app/serializers/alchemy/page_tree_serializer.rb +11 -31
- data/app/services/alchemy/copy_page.rb +17 -0
- data/app/services/alchemy/duplicate_element.rb +1 -1
- data/app/services/alchemy/page_tree_preloader.rb +105 -0
- data/app/stylesheets/alchemy/_extends.scss +3 -9
- data/app/stylesheets/alchemy/_mixins.scss +3 -1
- data/app/stylesheets/alchemy/_themes.scss +19 -10
- data/app/stylesheets/alchemy/admin/archive.scss +1 -0
- data/app/stylesheets/alchemy/admin/base.scss +5 -2
- data/app/stylesheets/alchemy/admin/buttons.scss +3 -3
- data/app/stylesheets/alchemy/admin/element-select.scss +18 -0
- data/app/stylesheets/alchemy/admin/elements.scss +123 -23
- data/app/stylesheets/alchemy/admin/errors.scss +17 -9
- data/app/stylesheets/alchemy/admin/flash.scss +6 -4
- data/app/stylesheets/alchemy/admin/images.scss +9 -5
- data/app/stylesheets/alchemy/admin/list_filter.scss +4 -4
- data/app/stylesheets/alchemy/admin/notices.scss +1 -2
- data/app/stylesheets/alchemy/admin/selects.scss +36 -21
- data/app/stylesheets/alchemy/admin/shoelace.scss +14 -1
- data/app/stylesheets/alchemy/admin/sitemap.scss +11 -3
- data/app/stylesheets/alchemy/admin/tags.scss +3 -1
- data/app/stylesheets/alchemy/admin/toolbar.scss +1 -1
- data/app/views/alchemy/_edit_mode.html.erb +1 -1
- data/app/views/alchemy/_menubar.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +35 -31
- data/app/views/alchemy/admin/attachments/_library_sidebar.html.erb +6 -0
- data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/_replace_button.html.erb +1 -8
- data/app/views/alchemy/admin/attachments/_sorting_select.html.erb +13 -0
- data/app/views/alchemy/admin/attachments/_tag_list.html.erb +2 -3
- data/app/views/alchemy/admin/attachments/index.html.erb +5 -11
- data/app/views/alchemy/admin/attachments/show.html.erb +1 -1
- data/app/views/alchemy/admin/clipboard/_button.html.erb +1 -0
- data/app/views/alchemy/admin/clipboard/index.html.erb +4 -5
- data/app/views/alchemy/admin/clipboard/insert.turbo_stream.erb +1 -1
- data/app/views/alchemy/admin/crop.html.erb +5 -7
- data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +6 -6
- data/app/views/alchemy/admin/elements/_fixed_element.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_footer.html.erb +7 -1
- data/app/views/alchemy/admin/elements/_header.html.erb +5 -5
- data/app/views/alchemy/admin/elements/_toolbar.html.erb +33 -8
- data/app/views/alchemy/admin/elements/create.turbo_stream.erb +10 -10
- data/app/views/alchemy/admin/elements/index.html.erb +29 -16
- data/app/views/alchemy/admin/elements/new.html.erb +2 -2
- data/app/views/alchemy/admin/ingredients/update.turbo_stream.erb +3 -5
- data/app/views/alchemy/admin/leave.html.erb +1 -1
- data/app/views/alchemy/admin/nodes/_node.html.erb +19 -0
- data/app/views/alchemy/admin/nodes/edit.html.erb +1 -1
- data/app/views/alchemy/admin/nodes/index.html.erb +3 -1
- data/app/views/alchemy/admin/nodes/new.html.erb +14 -1
- data/app/views/alchemy/admin/pages/_current_page.html.erb +3 -1
- data/app/views/alchemy/admin/pages/_form.html.erb +21 -9
- data/app/views/alchemy/admin/pages/_page_status.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +28 -26
- data/app/views/alchemy/admin/pages/_table.html.erb +0 -7
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +3 -5
- data/app/views/alchemy/admin/pages/edit.html.erb +5 -11
- data/app/views/alchemy/admin/pages/flush.turbo_stream.erb +2 -0
- data/app/views/alchemy/admin/pages/fold.turbo_stream.erb +5 -0
- data/app/views/alchemy/admin/pages/index.html.erb +5 -3
- data/app/views/alchemy/admin/pages/new.html.erb +2 -12
- data/app/views/alchemy/admin/pages/publish.turbo_stream.erb +12 -0
- data/app/views/alchemy/admin/pages/tree.html.erb +13 -0
- data/app/views/alchemy/admin/pages/update.turbo_stream.erb +5 -16
- data/app/views/alchemy/admin/partials/_flash_notices.html.erb +1 -1
- data/app/views/alchemy/admin/partials/{_remote_search_form.html.erb → _overlay_search_form.html.erb} +1 -2
- data/app/views/alchemy/admin/partials/_paste_from_clipboard_form.html.erb +12 -0
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +24 -21
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +18 -26
- data/app/views/alchemy/admin/pictures/_picture.html.erb +11 -15
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +3 -6
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +2 -3
- data/app/views/alchemy/admin/pictures/index.html.erb +0 -1
- data/app/views/alchemy/admin/pictures/update.turbo_stream.erb +1 -1
- data/app/views/alchemy/admin/resources/_resource_usage_info.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_tag_list.html.erb +2 -3
- data/app/views/alchemy/admin/styleguide/index.html.erb +25 -20
- data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
- data/app/views/alchemy/admin/tinymce/_setup.html.erb +2 -2
- data/app/views/alchemy/admin/uploader/_button.html.erb +1 -15
- data/app/views/alchemy/attachments/show.html.erb +1 -1
- data/app/views/alchemy/base/permission_denied.js.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_anchor.html.erb +9 -7
- data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +12 -5
- data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +10 -11
- data/app/views/alchemy/language_links/_spacer.html.erb +1 -1
- data/app/views/alchemy/messages_mailer/new.html.erb +1 -1
- data/app/views/alchemy/welcome.html.erb +1 -1
- data/config/locales/alchemy.en.yml +12 -2
- data/config/routes.rb +2 -2
- data/db/migrate/20230123112425_add_searchable_to_alchemy_pages.rb +1 -1
- data/db/migrate/20230505132743_add_indexes_to_alchemy_pictures.rb +1 -1
- data/db/migrate/20231113104432_create_page_mutexes.rb +1 -1
- data/db/migrate/20240314105244_create_alchemy_picture_descriptions.rb +1 -1
- data/db/migrate/20250626160259_add_unique_index_to_picture_descriptions.rb +1 -1
- data/db/migrate/20250905140323_add_created_at_index_to_pictures_and_attachments.rb +1 -1
- data/db/migrate/20251106150010_convert_select_value_for_multiple.rb +11 -0
- data/db/migrate/20260102121232_add_metadata_to_page_versions.rb +9 -0
- data/db/migrate/20260115164704_add_publication_timestamps_to_alchemy_elements.rb +30 -0
- data/db/migrate/20260115164705_add_index_to_element_publication_timestamps.rb +13 -0
- data/lib/alchemy/ability_helper.rb +1 -3
- data/lib/alchemy/auth_accessors.rb +51 -117
- data/lib/alchemy/configuration.rb +1 -0
- data/lib/alchemy/configurations/main.rb +63 -0
- data/lib/alchemy/controller_actions.rb +1 -1
- data/lib/alchemy/engine.rb +9 -12
- data/lib/alchemy/error_tracking/error_logger.rb +1 -1
- data/lib/alchemy/errors.rb +1 -1
- data/lib/alchemy/logger.rb +34 -4
- data/lib/alchemy/name_conversions.rb +0 -6
- data/lib/alchemy/seeder.rb +2 -2
- data/lib/alchemy/tasks/usage.rb +4 -4
- data/lib/alchemy/test_support/factories/page_version_factory.rb +3 -0
- data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +30 -0
- data/lib/alchemy/test_support/shared_ingredient_editor_examples.rb +26 -6
- data/lib/alchemy/test_support/shared_publishable_examples.rb +114 -0
- data/lib/alchemy/upgrader/eight_one.rb +56 -0
- data/lib/alchemy/upgrader.rb +9 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy.rb +1 -4
- data/lib/alchemy_cms.rb +0 -1
- data/lib/generators/alchemy/elements/templates/view.html.erb +3 -3
- data/lib/generators/alchemy/ingredient/ingredient_generator.rb +6 -8
- data/lib/generators/alchemy/ingredient/templates/editor_component.rb.tt +22 -0
- data/lib/generators/alchemy/page_layouts/templates/layout.html.erb +1 -1
- data/lib/generators/alchemy/site_layouts/templates/layout.html.erb +1 -1
- data/lib/tasks/alchemy/upgrade.rake +21 -7
- data/vendor/javascript/shoelace.min.js +713 -31
- data/vendor/javascript/tinymce.min.js +1 -1
- metadata +103 -83
- data/app/decorators/alchemy/element_editor.rb +0 -90
- data/app/helpers/alchemy/admin/pictures_helper.rb +0 -14
- data/app/javascript/alchemy_admin/file_editors.js +0 -28
- data/app/javascript/alchemy_admin/image_loader.js +0 -54
- data/app/javascript/alchemy_admin/page_sorter.js +0 -71
- data/app/javascript/alchemy_admin/sitemap.js +0 -154
- data/app/javascript/alchemy_admin/templates/page_folder.hbs +0 -3
- data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -4
- data/app/views/alchemy/admin/pages/_page.html.erb +0 -163
- data/app/views/alchemy/admin/pages/_sitemap.html.erb +0 -30
- data/app/views/alchemy/admin/pages/flush.js.erb +0 -2
- data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +0 -5
- data/app/views/alchemy/admin/pictures/index.js.erb +0 -2
- data/app/views/alchemy/ingredients/_audio_editor.html.erb +0 -5
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +0 -11
- data/app/views/alchemy/ingredients/_datetime_editor.html.erb +0 -20
- data/app/views/alchemy/ingredients/_file_editor.html.erb +0 -52
- data/app/views/alchemy/ingredients/_headline_editor.html.erb +0 -44
- data/app/views/alchemy/ingredients/_html_editor.html.erb +0 -8
- data/app/views/alchemy/ingredients/_link_editor.html.erb +0 -30
- data/app/views/alchemy/ingredients/_node_editor.html.erb +0 -13
- data/app/views/alchemy/ingredients/_number_editor.html.erb +0 -24
- data/app/views/alchemy/ingredients/_page_editor.html.erb +0 -13
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +0 -59
- data/app/views/alchemy/ingredients/_richtext_editor.html.erb +0 -15
- data/app/views/alchemy/ingredients/_select_editor.html.erb +0 -31
- data/app/views/alchemy/ingredients/_text_editor.html.erb +0 -29
- data/app/views/alchemy/ingredients/_video_editor.html.erb +0 -5
- data/lib/generators/alchemy/ingredient/templates/editor.html.erb +0 -14
- /data/{lib → app/models}/alchemy/permissions.rb +0 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.shared_examples_for "being publishable" do |factory_name|
|
|
4
|
+
describe ".draft" do
|
|
5
|
+
let!(:draft_versions) { create_list(factory_name, 2, public_on: nil) }
|
|
6
|
+
|
|
7
|
+
subject { described_class.draft.map(&:public_on) }
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
create(factory_name, public_on: Time.current)
|
|
11
|
+
subject.uniq!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "only includes records without public_on date" do
|
|
15
|
+
expect(subject).to eq [nil]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe ".scheduled" do
|
|
20
|
+
subject { described_class.scheduled }
|
|
21
|
+
|
|
22
|
+
let!(:public_one) { create(factory_name, public_on: Date.yesterday) }
|
|
23
|
+
let!(:public_two) { create(factory_name, public_on: Time.current) }
|
|
24
|
+
let!(:non_public) { create(factory_name, public_on: nil) }
|
|
25
|
+
|
|
26
|
+
it "returns currently scheduled records" do
|
|
27
|
+
# Filter to test records only, as factories may create additional records as side effects
|
|
28
|
+
scheduled = subject.where(id: [public_one.id, public_two.id, non_public.id])
|
|
29
|
+
expect(scheduled).to match_array([
|
|
30
|
+
public_one,
|
|
31
|
+
public_two
|
|
32
|
+
])
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe ".published" do
|
|
37
|
+
let!(:public_one) { create(factory_name, public_on: Date.yesterday) }
|
|
38
|
+
let!(:public_two) { create(factory_name, public_on: Date.tomorrow) }
|
|
39
|
+
let!(:non_public) { create(factory_name, public_on: nil) }
|
|
40
|
+
|
|
41
|
+
context "without time given" do
|
|
42
|
+
subject { described_class.published }
|
|
43
|
+
|
|
44
|
+
it "returns records currently public" do
|
|
45
|
+
# Filter to test records only, as factories may create additional records as side effects
|
|
46
|
+
published = subject.where(id: [public_one.id, public_two.id, non_public.id])
|
|
47
|
+
expect(published).to match_array([
|
|
48
|
+
public_one
|
|
49
|
+
])
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "with time given" do
|
|
54
|
+
subject { described_class.published(at: Date.tomorrow + 1.day) }
|
|
55
|
+
|
|
56
|
+
it "returns records public on that time" do
|
|
57
|
+
# Filter to test records only, as factories may create additional records as side effects
|
|
58
|
+
published = subject.where(id: [public_one.id, public_two.id, non_public.id])
|
|
59
|
+
expect(published).to match_array([
|
|
60
|
+
public_one,
|
|
61
|
+
public_two
|
|
62
|
+
])
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "#public?" do
|
|
68
|
+
subject { page_version.public? }
|
|
69
|
+
|
|
70
|
+
context "when public_on is not set" do
|
|
71
|
+
let(:page_version) { build(factory_name, public_on: nil) }
|
|
72
|
+
|
|
73
|
+
it { is_expected.to be(false) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context "when public_on is set to past date" do
|
|
77
|
+
context "and public_until is set to nil" do
|
|
78
|
+
let(:page_version) do
|
|
79
|
+
build(factory_name,
|
|
80
|
+
public_on: Time.current - 2.days,
|
|
81
|
+
public_until: nil)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it { is_expected.to be(true) }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "and public_until is set to future date" do
|
|
88
|
+
let(:page_version) do
|
|
89
|
+
build(factory_name,
|
|
90
|
+
public_on: Time.current - 2.days,
|
|
91
|
+
public_until: Time.current + 2.days)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it { is_expected.to be(true) }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context "and public_until is set to past date" do
|
|
98
|
+
let(:page_version) do
|
|
99
|
+
build(factory_name,
|
|
100
|
+
public_on: Time.current - 2.days,
|
|
101
|
+
public_until: Time.current - 1.days)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it { is_expected.to be(false) }
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context "when public_on is set to future date" do
|
|
109
|
+
let(:page_version) { build(factory_name, public_on: Time.current + 2.days) }
|
|
110
|
+
|
|
111
|
+
it { is_expected.to be(false) }
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Alchemy
|
|
4
|
+
class Upgrader
|
|
5
|
+
module EightOne
|
|
6
|
+
def migrate_page_metadata
|
|
7
|
+
desc "Migrating page metadata to page versions"
|
|
8
|
+
|
|
9
|
+
connection = ActiveRecord::Base.connection
|
|
10
|
+
pages_table = Alchemy::Page.table_name
|
|
11
|
+
versions_table = Alchemy::PageVersion.table_name
|
|
12
|
+
|
|
13
|
+
unmigrated_count = connection.select_value(<<-SQL.strip_heredoc).to_i
|
|
14
|
+
SELECT COUNT(*) FROM #{versions_table}
|
|
15
|
+
WHERE title IS NULL
|
|
16
|
+
AND meta_description IS NULL
|
|
17
|
+
AND meta_keywords IS NULL
|
|
18
|
+
SQL
|
|
19
|
+
|
|
20
|
+
if unmigrated_count == 0
|
|
21
|
+
log "All page versions have meta data.", :skip
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
sql = if connection.adapter_name.downcase.match?(/mysql|trilogy/)
|
|
26
|
+
<<-SQL.strip_heredoc
|
|
27
|
+
UPDATE #{versions_table} pv
|
|
28
|
+
INNER JOIN #{pages_table} p ON pv.page_id = p.id
|
|
29
|
+
SET pv.title = p.title,
|
|
30
|
+
pv.meta_description = p.meta_description,
|
|
31
|
+
pv.meta_keywords = p.meta_keywords
|
|
32
|
+
WHERE pv.title IS NULL
|
|
33
|
+
AND pv.meta_description IS NULL
|
|
34
|
+
AND pv.meta_keywords IS NULL
|
|
35
|
+
SQL
|
|
36
|
+
else
|
|
37
|
+
<<-SQL.strip_heredoc
|
|
38
|
+
UPDATE #{versions_table}
|
|
39
|
+
SET title = p.title,
|
|
40
|
+
meta_description = p.meta_description,
|
|
41
|
+
meta_keywords = p.meta_keywords
|
|
42
|
+
FROM #{pages_table} p
|
|
43
|
+
WHERE #{versions_table}.page_id = p.id
|
|
44
|
+
AND #{versions_table}.title IS NULL
|
|
45
|
+
AND #{versions_table}.meta_description IS NULL
|
|
46
|
+
AND #{versions_table}.meta_keywords IS NULL
|
|
47
|
+
SQL
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
migrated_count = connection.update(sql)
|
|
51
|
+
|
|
52
|
+
log "Migrated metadata for #{migrated_count} page versions."
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/alchemy/upgrader.rb
CHANGED
|
@@ -12,11 +12,19 @@ module Alchemy
|
|
|
12
12
|
Dir["#{File.dirname(__FILE__)}/upgrader/*.rb"].sort.each { require(_1) }
|
|
13
13
|
|
|
14
14
|
VERSION_MODULE_MAP = {
|
|
15
|
-
"8.0" => "Alchemy::Upgrader::EightZero"
|
|
15
|
+
"8.0" => "Alchemy::Upgrader::EightZero",
|
|
16
|
+
"8.1" => "Alchemy::Upgrader::EightOne"
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
source_root Alchemy::Engine.root.join("lib/generators/alchemy/install")
|
|
19
20
|
|
|
21
|
+
# Returns a memoized upgrader instance for the given version.
|
|
22
|
+
# This ensures todos are accumulated across rake tasks.
|
|
23
|
+
def self.[](version)
|
|
24
|
+
@instances ||= {}
|
|
25
|
+
@instances[version.to_s] ||= new(version)
|
|
26
|
+
end
|
|
27
|
+
|
|
20
28
|
def initialize(version)
|
|
21
29
|
super()
|
|
22
30
|
self.class.include VERSION_MODULE_MAP[version.to_s].constantize
|
data/lib/alchemy/version.rb
CHANGED
data/lib/alchemy.rb
CHANGED
|
@@ -21,10 +21,7 @@ module Alchemy
|
|
|
21
21
|
def config
|
|
22
22
|
@_config ||= Alchemy::Configurations::Main.new
|
|
23
23
|
end
|
|
24
|
-
|
|
25
|
-
def configure(&blk)
|
|
26
|
-
yield config
|
|
27
|
-
end
|
|
24
|
+
delegate :configure, to: :config
|
|
28
25
|
|
|
29
26
|
enable_searchable_deprecation_msg = "Use `Alchemy.config.show_page_searchable_checkbox` instead."
|
|
30
27
|
def enable_searchable = config.show_page_searchable_checkbox
|
data/lib/alchemy_cms.rb
CHANGED
|
@@ -42,7 +42,6 @@ require_relative "alchemy/name_conversions"
|
|
|
42
42
|
require_relative "alchemy/on_page_layout"
|
|
43
43
|
require_relative "alchemy/on_page_layout/callbacks_runner"
|
|
44
44
|
require_relative "alchemy/paths"
|
|
45
|
-
require_relative "alchemy/permissions"
|
|
46
45
|
require_relative "alchemy/tinymce"
|
|
47
46
|
require_relative "alchemy/taggable"
|
|
48
47
|
require_relative "alchemy/version"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
<%% cache(<%= @element_name %>) do -%>
|
|
2
2
|
<%%= element_view_for(<%= @element_name %>) do |el| -%>
|
|
3
3
|
<%- @ingredients.each do |ingredient| -%>
|
|
4
4
|
<%- if @ingredients.length > 1 -%>
|
|
@@ -12,5 +12,5 @@
|
|
|
12
12
|
<%- if @element['nestable_elements'].present? -%>
|
|
13
13
|
<%%= render <%= @element_name %>.nested_elements.published %>
|
|
14
14
|
<%- end -%>
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
<%% end -%>
|
|
16
|
+
<%% end -%>
|
|
@@ -11,20 +11,18 @@ module Alchemy
|
|
|
11
11
|
|
|
12
12
|
def init
|
|
13
13
|
@class_name = class_name.classify
|
|
14
|
-
@ingredients_view_path = "app/views/alchemy/ingredients"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def create_view_component
|
|
18
|
-
template "view_component.rb.tt", "app/components/alchemy/ingredients/#{file_name}_view.rb"
|
|
19
14
|
end
|
|
20
15
|
|
|
21
16
|
def create_model
|
|
22
17
|
template "model.rb.tt", "app/models/alchemy/ingredients/#{file_name}.rb"
|
|
23
18
|
end
|
|
24
19
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
def create_view_component
|
|
21
|
+
template "view_component.rb.tt", "app/components/alchemy/ingredients/#{file_name}_view.rb"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def create_editor_component
|
|
25
|
+
template "editor_component.rb.tt", "app/components/alchemy/ingredients/#{file_name}_editor.rb"
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
def show_todo
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Alchemy
|
|
4
|
+
module Ingredients
|
|
5
|
+
class <%= @class_name %>Editor < BaseEditor
|
|
6
|
+
# Override the input_field method to customize the editor input.
|
|
7
|
+
# The base implementation renders a text field.
|
|
8
|
+
#
|
|
9
|
+
# def input_field
|
|
10
|
+
# tag.div(class: "input-field") do
|
|
11
|
+
# text_field_tag(form_field_name,
|
|
12
|
+
# value,
|
|
13
|
+
# id: form_field_id,
|
|
14
|
+
# minlength: length_validation&.fetch(:minimum, nil),
|
|
15
|
+
# maxlength: length_validation&.fetch(:maximum, nil),
|
|
16
|
+
# required: presence_validation?,
|
|
17
|
+
# pattern: format_validation)
|
|
18
|
+
# end
|
|
19
|
+
# end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<%%= render_elements %>
|
|
1
|
+
<%%= render_elements %>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<%%= yield %>
|
|
1
|
+
<%%= yield %>
|
|
@@ -3,16 +3,15 @@
|
|
|
3
3
|
require "alchemy/upgrader"
|
|
4
4
|
require "alchemy/version"
|
|
5
5
|
|
|
6
|
-
Upgrader = Alchemy::Upgrader.new("8.0")
|
|
7
|
-
|
|
8
6
|
namespace :alchemy do
|
|
9
7
|
desc "Upgrades your app to AlchemyCMS v#{Alchemy::VERSION}."
|
|
10
8
|
task upgrade: [
|
|
11
9
|
"alchemy:upgrade:prepare",
|
|
12
|
-
"alchemy:upgrade:8.0:run"
|
|
10
|
+
"alchemy:upgrade:8.0:run",
|
|
11
|
+
"alchemy:upgrade:8.1:run"
|
|
13
12
|
] do
|
|
14
|
-
Upgrader.run_migrations
|
|
15
|
-
Upgrader.display_todos
|
|
13
|
+
Alchemy::Upgrader["8.1"].run_migrations
|
|
14
|
+
Alchemy::Upgrader["8.1"].display_todos
|
|
16
15
|
end
|
|
17
16
|
|
|
18
17
|
namespace :upgrade do
|
|
@@ -29,7 +28,7 @@ namespace :alchemy do
|
|
|
29
28
|
|
|
30
29
|
desc "Alchemy Upgrader: Update configuration file."
|
|
31
30
|
task config: [:environment] do
|
|
32
|
-
Upgrader.update_config
|
|
31
|
+
Alchemy::Upgrader["8.0"].update_config
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
namespace "8.0" do
|
|
@@ -38,7 +37,22 @@ namespace :alchemy do
|
|
|
38
37
|
]
|
|
39
38
|
|
|
40
39
|
task :mention_alchemy_config_initializer do
|
|
41
|
-
Upgrader.mention_alchemy_config_initializer
|
|
40
|
+
Alchemy::Upgrader["8.0"].mention_alchemy_config_initializer
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
namespace "8.1" do
|
|
45
|
+
task "run" => [
|
|
46
|
+
"alchemy:upgrade:8.1:migrate_page_metadata"
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
desc "Migrate page metadata to page versions"
|
|
50
|
+
task migrate_page_metadata: [
|
|
51
|
+
"alchemy:install:migrations",
|
|
52
|
+
"environment"
|
|
53
|
+
] do
|
|
54
|
+
Alchemy::Upgrader["8.1"].run_migrations
|
|
55
|
+
Alchemy::Upgrader["8.1"].migrate_page_metadata
|
|
42
56
|
end
|
|
43
57
|
end
|
|
44
58
|
end
|