From 9b816b29dc03396a6872ed9287e98ce56c5eb815 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Mon, 22 Mar 2021 11:15:53 +0100 Subject: [PATCH 1/2] Decorate contents in element editor Instead of in the view --- app/decorators/alchemy/element_editor.rb | 6 ++++++ app/views/alchemy/admin/elements/_element.html.erb | 2 +- spec/decorators/alchemy/element_editor_spec.rb | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/decorators/alchemy/element_editor.rb b/app/decorators/alchemy/element_editor.rb index 0b7512c4a5..04246f3b5a 100644 --- a/app/decorators/alchemy/element_editor.rb +++ b/app/decorators/alchemy/element_editor.rb @@ -8,6 +8,12 @@ def to_partial_path "alchemy/admin/elements/element" end + def contents + element.contents.map do |content| + Alchemy::ContentEditor.new(content) + end + end + # CSS classes for the element editor partial. def css_classes [ diff --git a/app/views/alchemy/admin/elements/_element.html.erb b/app/views/alchemy/admin/elements/_element.html.erb index f4d4cad029..c759556c04 100644 --- a/app/views/alchemy/admin/elements/_element.html.erb +++ b/app/views/alchemy/admin/elements/_element.html.erb @@ -25,7 +25,7 @@
- <%= render element.contents.map { |content| Alchemy::ContentEditor.new(content) } %> + <%= render element.contents %>
<% if element.taggable? %> diff --git a/spec/decorators/alchemy/element_editor_spec.rb b/spec/decorators/alchemy/element_editor_spec.rb index e9cfc3e7d5..75b5556056 100644 --- a/spec/decorators/alchemy/element_editor_spec.rb +++ b/spec/decorators/alchemy/element_editor_spec.rb @@ -12,6 +12,20 @@ end end + describe "#contents" do + let(:element) { create(:alchemy_element, :with_contents) } + + 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 + end + describe "#to_partial_path" do subject { element_editor.to_partial_path } From e7b8e148a028a33ec8fce0b66aad72eeadb0db58 Mon Sep 17 00:00:00 2001 From: Thomas von Deyen Date: Mon, 22 Mar 2021 13:27:09 +0100 Subject: [PATCH 2/2] Create defined contents if they are missing If new contents have been defined on the elements definition, but they are not existing yet we create them on demand. This happens during rendering (speak loading) elements in the elements window during page edit. Ideally we would only instantiate them, but since the content editors expect a persisted content we cannot do that. This also closes #2031 --- app/decorators/alchemy/element_editor.rb | 23 ++++++++++++++-- .../decorators/alchemy/element_editor_spec.rb | 26 ++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/app/decorators/alchemy/element_editor.rb b/app/decorators/alchemy/element_editor.rb index 04246f3b5a..ff6e11903b 100644 --- a/app/decorators/alchemy/element_editor.rb +++ b/app/decorators/alchemy/element_editor.rb @@ -8,9 +8,14 @@ def to_partial_path "alchemy/admin/elements/element" end + # Returns content editor instances for defined contents + # + # Creates contents on demand if the content is not yet present on the element + # + # @return Array def contents - element.contents.map do |content| - Alchemy::ContentEditor.new(content) + element.definition.fetch(:contents, []).map do |content| + Alchemy::ContentEditor.new(find_or_create_content(content[:name])) end end @@ -84,5 +89,19 @@ def deprecation_notice default: Alchemy.t(:element_deprecated)) end end + + private + + def find_or_create_content(name) + find_content(name) || create_content(name) + end + + def find_content(name) + element.contents.find { |content| content.name == name } + end + + def create_content(name) + Alchemy::Content.create(element: element, name: name) + end end end diff --git a/spec/decorators/alchemy/element_editor_spec.rb b/spec/decorators/alchemy/element_editor_spec.rb index 75b5556056..bca04dc838 100644 --- a/spec/decorators/alchemy/element_editor_spec.rb +++ b/spec/decorators/alchemy/element_editor_spec.rb @@ -13,7 +13,7 @@ end describe "#contents" do - let(:element) { create(:alchemy_element, :with_contents) } + let(:element) { create(:alchemy_element, :with_contents, name: "headline") } subject(:contents) { element_editor.contents } @@ -24,6 +24,30 @@ 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 "#to_partial_path" do