Skip to content

Commit

Permalink
Render ingredients as view components
Browse files Browse the repository at this point in the history
Instead of rendering the view partial of the ingredient
we render it view component instead.

Deprecates the ingredients view partials.
  • Loading branch information
tvdeyen committed May 16, 2023
1 parent 9934011 commit f36872d
Show file tree
Hide file tree
Showing 24 changed files with 126 additions and 51 deletions.
2 changes: 1 addition & 1 deletion app/components/alchemy/ingredients/datetime_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Ingredients
class DatetimeView < BaseView
# @param ingredient [Alchemy::Ingredient]
# @param date_format [String] The date format to use. Use either a strftime format string, a I18n format symbol or "rfc822".
def initialize(ingredient, date_format: nil)
def initialize(ingredient, date_format: nil, html_options: {})
super(ingredient)
@date_format = date_format
end
Expand Down
2 changes: 1 addition & 1 deletion app/components/alchemy/ingredients/richtext_view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class RichtextView < BaseView

# @param ingredient [Alchemy::Ingredient]
# @param plain_text [Boolean] (false) Whether to show as plain text or with markup
def initialize(ingredient, plain_text: nil)
def initialize(ingredient, plain_text: nil, html_options: {})
super(ingredient)
@plain_text = plain_text.nil? ? ingredient.settings.fetch(:plain_text, false) : plain_text
end
Expand Down
10 changes: 6 additions & 4 deletions app/helpers/alchemy/elements_block_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ def render(name, options = {}, html_options = {})
renderable = element.ingredient_by_role(name)
return if renderable.nil?

helpers.render(renderable, {
options: options,
html_options: html_options
})
helpers.render(
renderable.as_view_component(
options: options,
html_options: html_options
)
)
end

# Returns the value of one of the element's ingredients.
Expand Down
15 changes: 15 additions & 0 deletions app/helpers/alchemy/elements_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,5 +210,20 @@ def element_tags_attributes(element, options = {})

{"data-element-tags" => options[:formatter].call(element.tag_list)}
end

def ingredient_view_deprecation_notice(ingredient, file)
Alchemy::Deprecation.warn(<<~WARN)
rendering `alchemy/ingredients/#{file.split("/").last.sub(/^_/, "")}` partial is deprecated.
Please render the view component directly instead:
<%= render ingredient.as_view_component %>
or use the `el.render` helper inside a `element_view_for` helper:
<%= el.render(:#{ingredient.role}) %>
WARN
end
end
end
12 changes: 12 additions & 0 deletions app/models/alchemy/ingredient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,20 @@ def preview_ingredient?
!!definition[:as_element_title]
end

# The view component of the ingredient with mapped options.
#
# @param options [Hash] - Passed to the view component as keyword arguments
# @param html_options [Hash] - Passed to the view component
def as_view_component(options: {}, html_options: {})
view_component_class.new(self, **options, html_options: html_options)
end

private

def view_component_class
@_view_component_class ||= "#{self.class.name}View".constantize
end

def hint_translation_attribute
role
end
Expand Down
18 changes: 18 additions & 0 deletions app/models/alchemy/ingredients/picture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ class Picture < Alchemy::Ingredient
def preview_text(max_length = 30)
picture&.name.to_s[0..max_length - 1]
end

# The picture view component with mapped options.
#
# @param options [Hash] - Passed to the view component
# @param html_options [Hash] - Passed to the view component
#
# @return Alchemy::Ingredients::PictureView
def as_view_component(options: {}, html_options: {})
PictureView.new(
self,
show_caption: options.delete(:show_caption),
disable_link: options.delete(:disable_link),
srcset: options.delete(:srcset),
sizes: options.delete(:sizes),
picture_options: options,
html_options: html_options
)
end
end
end
end
3 changes: 2 additions & 1 deletion app/views/alchemy/ingredients/_audio_view.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<%= render Alchemy::Ingredients::AudioView.new(audio_view) -%>
<%- ingredient_view_deprecation_notice(audio_view, __FILE__) -%>
<%= render audio_view.as_view_component -%>
3 changes: 2 additions & 1 deletion app/views/alchemy/ingredients/_boolean_view.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<%= render Alchemy::Ingredients::BooleanView.new(boolean_view) -%>
<%- ingredient_view_deprecation_notice(boolean_view, __FILE__) -%>
<%= render boolean_view.as_view_component -%>
4 changes: 2 additions & 2 deletions app/views/alchemy/ingredients/_datetime_view.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<%= render Alchemy::Ingredients::DatetimeView.new(
datetime_view,
<%- ingredient_view_deprecation_notice(datetime_view, __FILE__) -%>
<%= render datetime_view.as_view_component(
**local_assigns.slice(:options)
) -%>
8 changes: 4 additions & 4 deletions app/views/alchemy/ingredients/_file_view.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= render Alchemy::Ingredients::FileView.new(
file_view,
link_text: local_assigns.fetch(:options, {})[:link_text],
html_options: local_assigns.fetch(:html_options, {})
<%- ingredient_view_deprecation_notice(file_view, __FILE__) -%>
<%= render file_view.as_view_component(
**local_assigns.slice(:options),
**local_assigns.slice(:html_options)
) -%>
5 changes: 3 additions & 2 deletions app/views/alchemy/ingredients/_headline_view.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<%= render Alchemy::Ingredients::HeadlineView.new(
headline_view,
<%- ingredient_view_deprecation_notice(headline_view, __FILE__) -%>
<%= render headline_view.as_view_component(
**local_assigns.slice(:options),
**local_assigns.slice(:html_options)
) -%>
3 changes: 2 additions & 1 deletion app/views/alchemy/ingredients/_html_view.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<%= render Alchemy::Ingredients::HtmlView.new(html_view) -%>
<%- ingredient_view_deprecation_notice(html_view, __FILE__) -%>
<%= render html_view.as_view_component -%>
8 changes: 4 additions & 4 deletions app/views/alchemy/ingredients/_link_view.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= render Alchemy::Ingredients::LinkView.new(
link_view,
text: local_assigns.fetch(:options, {})[:text],
html_options: local_assigns.fetch(:html_options, {})
<%- ingredient_view_deprecation_notice(link_view, __FILE__) -%>
<%= render link_view.as_view_component(
**local_assigns.slice(:options),
**local_assigns.slice(:html_options)
) -%>
3 changes: 2 additions & 1 deletion app/views/alchemy/ingredients/_node_view.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<%= render Alchemy::Ingredients::NodeView.new(node_view) -%>
<%- ingredient_view_deprecation_notice(node_view, __FILE__) -%>
<%= render node_view.as_view_component -%>
3 changes: 2 additions & 1 deletion app/views/alchemy/ingredients/_page_view.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<%= render Alchemy::Ingredients::PageView.new(page_view) -%>
<%- ingredient_view_deprecation_notice(page_view, __FILE__) -%>
<%= render page_view.as_view_component -%>
13 changes: 4 additions & 9 deletions app/views/alchemy/ingredients/_picture_view.html.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
<%- options = local_assigns.fetch(:options, {}) -%>
<%= render Alchemy::Ingredients::PictureView.new(
picture_view,
show_caption: options.delete(:show_caption),
disable_link: options.delete(:disable_link),
srcset: options.delete(:srcset),
sizes: options.delete(:sizes),
picture_options: options,
html_options: local_assigns.fetch(:html_options, {})
<%- ingredient_view_deprecation_notice(picture_view, __FILE__) -%>
<%= render picture_view.as_view_component(
**local_assigns.slice(:options),
**local_assigns.slice(:html_options)
) -%>
6 changes: 3 additions & 3 deletions app/views/alchemy/ingredients/_richtext_view.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<%= render Alchemy::Ingredients::RichtextView.new(
richtext_view,
plain_text: local_assigns.fetch(:options, {})[:plain_text],
<%- ingredient_view_deprecation_notice(richtext_view, __FILE__) -%>
<%= render richtext_view.as_view_component(
**local_assigns.slice(:options)
) -%>
3 changes: 2 additions & 1 deletion app/views/alchemy/ingredients/_select_view.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<%= render Alchemy::Ingredients::SelectView.new(select_view) -%>
<%- ingredient_view_deprecation_notice(select_view, __FILE__) -%>
<%= render select_view.as_view_component -%>
8 changes: 4 additions & 4 deletions app/views/alchemy/ingredients/_text_view.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%= render Alchemy::Ingredients::TextView.new(
text_view,
disable_link: local_assigns.dig(:options, :disable_link),
html_options: local_assigns.fetch(:html_options, {})
<%- ingredient_view_deprecation_notice(text_view, __FILE__) -%>
<%= render text_view.as_view_component(
**local_assigns.slice(:options),
**local_assigns.slice(:html_options)
) -%>
3 changes: 2 additions & 1 deletion app/views/alchemy/ingredients/_video_view.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<%= render Alchemy::Ingredients::VideoView.new(video_view) -%>
<%- ingredient_view_deprecation_notice(video_view, __FILE__) -%>
<%= render video_view.as_view_component -%>
6 changes: 6 additions & 0 deletions lib/alchemy/test_support/shared_ingredient_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,10 @@
end
end
end

describe "#as_view_component" do
subject { ingredient.as_view_component }

it { is_expected.to be_a("#{described_class}View".constantize) }
end
end
2 changes: 1 addition & 1 deletion spec/controllers/alchemy/pages_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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").ingredients.texts.first.update_column(:value, "screwdriver")
product.elements.find_by(name: "article").ingredients.texts.first.update_column(:value, "screwdriver")
end

context "with correct levelnames in params" do
Expand Down
25 changes: 16 additions & 9 deletions spec/helpers/alchemy/elements_block_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,25 @@ module Alchemy
end

describe "#render" do
let(:scope) { double(render: "<alchemy-ingredient>") }

context "with element having ingredients" do
let(:element) { create(:alchemy_element, :with_ingredients) }
let(:ingredient) { element.ingredient_by_role(:headline) }
let(:element) { create(:alchemy_element, name: :header, autogenerate_ingredients: true) }
let(:ingredient) { element.ingredient_by_role(:image) }

it "passes options and html_options to view component class" do
expect(ingredient).to receive(:as_view_component).with(
options: {disable_link: true},
html_options: {class: "foo"}
)
subject.render(:image, {disable_link: true}, {class: "foo"})
end

it "delegates to Rails' render helper" do
expect(scope).to receive(:render).with(ingredient, {
options: {
foo: "bar"
},
html_options: {}
})
subject.render(:headline, foo: "bar")
expect(scope).to receive(:render).with(
an_instance_of(Alchemy::Ingredients::PictureView)
)
subject.render(:image)
end
end
end
Expand Down
12 changes: 12 additions & 0 deletions spec/models/alchemy/ingredient_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,4 +259,16 @@

it { is_expected.to be(false) }
end

describe "#as_view_component" do
let(:ingredient) { Alchemy::Ingredients::Text.new(role: "intro", element: element) }

it "passes options as keyword arguments to view component class" do
expect(Alchemy::Ingredients::TextView).to receive(:new).with(ingredient, disable_link: true, html_options: {class: "foo"})
ingredient.as_view_component(
options: {disable_link: true},
html_options: {class: "foo"}
)
end
end
end

0 comments on commit f36872d

Please sign in to comment.