-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check for existence of product_path
instead of Spree::Frontend::Engine
#4278
Check for existence of product_path
instead of Spree::Frontend::Engine
#4278
Conversation
Thanks for your PR, @gsmendoza. I think it's a great idea to replace the check of the engine's class with something else. However, I'm afraid checking for the presence of a concrete route is not a very robust solution. What about configuring that route in the backend and defaulting to |
Do you mean something like this, @waiting-for-dev ? # backend/lib/spree/backend_configuration.rb
module Spree
class BackendConfiguration < Preferences::Configuration
preference :locale, :string, default: I18n.default_locale
preference :product_path_method, :string, default: :product_path
end
end <% if spree.respond_to?(Spree::Backend::Config[:product_path_method]) %>
<li id="view_product_link">
<%= link_to t('spree.view_product'), spree.public_send(Spree::Backend::Config[:product_path_method], @product), id: 'admin_view_product', class: 'btn btn-default ml-2' %>
</li>
<% end %> |
Yes, but maybe we could be more flexible and allow custom user-defined routes (i.e., not within preference :product_path_method, :string, default: Rails.application.routes.url_helpers.spree.product_path |
@waiting-for-dev Sounds good! I'll give it a try 👍 |
@waiting-for-dev I'm still researching if this is possible, but this is what I have completed so far:
One alternative I am thinking is to extract the
And we'd call it from the view like this: <% if Spree::Backend::Config[:product_link_partial_path] %>
<%= render partial: Spree::Backend::Config[:product_link_partial_path] %>
<% end %> SolidusStarterFrontend-based apps can provide their own What do you think of this option? |
Hmm, I see. However, using a partial for that is rather cumbersome. We can wrap in a proc and provide the view context. Something like: preference :frontend_product_path, :proc, default: proc { ->(template_context) { template_context.spree.product_path } } Then, from the template: <%= Spree::Backend::Config[:frontend_product_path].call(self) %> Ideally, we should narrow the scope of the argument we're giving to the proc (i.e., only providing access to the route helpers), but I don't know if that's possible from the template. BTW, the default proc needs to be nested because the outer one is used to manage loading different returned values depending on the loaded Solidus version. |
@waiting-for-dev Sounds good! I'll give it a try 👍 |
->(template_context, product) { | ||
return unless template_context.spree.respond_to?(:product_path) | ||
|
||
template_context.spree.product_path(product) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@waiting-for-dev Appreciate to head your thoughts on this fixup. Prior to this PR, the behavior of the backend product link is as follows:
- If the app has a frontend component, the backend would display the link. For instance, this is the behavior of the Solidus sandbox app.
- If the app does not have a frontend component, the backend would NOT display the product link. This is how the backend feature spec suite behaves, since it does not have an integrated frontend.
I've attempted to maintain this behavior in this default value for the frontend_product_path
preference. What do you think? On the upside, it doesn't introduce changes to the feature. However, on the downside, it seems to look a bit complicated for a default value.
The good news is that if an app has to override this frontend_product_path
, it does not necessarily have to match the behavior of this default value. In particular, for a Starter FE-based app, the app already knows that it has a frontend, so it can skip the respond_to?(:product_path)
guard:
# config/initializers/spree.rb
Spree::Backend::Config.configure do |config|
config.frontend_product_path = ->(template_context, product) { template_context.spree.product_path(product) }
end
If you feel that the default value for frontend_product_path
is too complicated, I think the next best alternative is to set the default value to nil, like this:
# backend/lib/spree/backend_configuration.rb
preference :frontend_product_path, :proc, default: nil
<!-- backend/app/views/spree/admin/products/edit.html.erb ->
<% if Spree::Backend::Config[:frontend_product_path] %>
<li id="view_product_link">
<%= link_to t('spree.view_product'), Spree::Backend::Config[:frontend_product_path].call(self, @product), id: 'admin_view_product', class: 'btn btn-default ml-2' %>
</li>
<% end %>
I think this implementation is straightforward and it allows the backend feature spec suite to pass without any changes. The downside is that this is a breaking change: users would have to override this preference if they would like to continue showing the product link on their backend.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @gsmendoza, I see your point. I'd stick with the first one. You're right; it's complicated, but it's what it's giving us the behavior we need 🙂 Nothing guarantees us that the method product_path
is present, so, yeah, we need to check it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@waiting-for-dev Cool! I'll go ahead with implementing the first option 👍
4f1c10f
to
f7ed0fe
Compare
…gine` Goal ---- We want to update the Edit Product page to check for existence of `product_path` instead of `Spree::Frontend::Engine` so that the Edit Product page would work with a frontend generated by SolidusStarterFrontend. Requirements ------------ *Admin can find a link to the product in the Edit Product page if the app has a frontend* Given I am an admin of a Solidus app And the app has a product page i.e. it has a frontend When I go to the Edit Product page Then I should see a link to the product page *Admin won't find a link to the product in the Edit Product page if the app does not have a frontend* Given I am an admin of a Solidus app And the app has does not have a product page i.e. it does not have a frontend When I go to the Edit Product page Then I should not see a link to the product page
f7ed0fe
to
f6ba03c
Compare
@waiting-for-dev I've updated the PR. Appreciate if you can take a look. You can find my updated manual test at https://user-images.githubusercontent.com/61476/156317692-f7cf2e8f-7f8f-40b3-bc49-1024821a04a2.mp4. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @gsmendoza!! Great job! I just left a non-blocking suggestion 🙂
@@ -4,9 +4,9 @@ | |||
<%= link_to t('spree.new_product'), new_object_url, id: 'admin_new_product', class: 'btn btn-primary' %> | |||
</li> | |||
<% end %> | |||
<% if defined?(Spree::Frontend::Engine) %> | |||
<% if Spree::Backend::Config[:frontend_product_path].call(self, @product) %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are your thoughts about moving it to a helper? I think it's too much logic to be in the template.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@waiting-for-dev Do you mean a helper for the frontend_product_path
like this?
# backend/app/helpers/spree/admin/products_helper.rb
module Spree
module Admin
module ProductsHelper
def frontend_product_path(product)
# Not sure about the `self` here, but I think it will work.
Spree::Backend::Config[:frontend_product_path].call(self, @product)
end
end
end
end
<%# backend/app/views/spree/admin/products/edit.html.erb %>
<% if frontend_product_path(@product) %>
<li id="view_product_link">
<%= link_to t('spree.view_product'), frontend_product_path(@product), id: 'admin_view_product', class: 'btn btn-default ml-2' %>
</li>
<% end %>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I mean that! But I leave it to your discretion 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@waiting-for-dev Cool! I added the helper :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙌 🙌 thanks, @gsmendoza!!
Goal
We want to update the Edit Product page to check for existence of
product_path
instead ofSpree::Frontend::Engine
so that the EditProduct page would work with a frontend generated by
SolidusStarterFrontend.
Background
This PR is part of an ongoing effort to replace
solidus_frontend
in Solidus with SolidusStarterFrotntend:eng-293-product-path.mp4
Requirements
Admin can find a link to the product in the Edit Product page if the app has a frontend
Given I am an admin of a Solidus app
And the app has a product page i.e. it has a frontend
When I go to the Edit Product page
Then I should see a link to the product page
Admin won't find a link to the product in the Edit Product page if the app does not have a frontend
Given I am an admin of a Solidus app
And the app has does not have a product page i.e. it does not have a
frontend
When I go to the Edit Product page
Then I should not see a link to the product page
Manual tests
eng-293-update-solidus-backend-productsedit--demo.mp4
2022-03-02 update
eng-293-update-solidus-backend-productsedit--demo-2.mp4
Checklist: