Followup on #2894052: Hide add to cart form in disabled product variants: This module no longer displays a form if the product variation is disabled, consistent with standard Commerce behaviour. That is not a problem for the standard Commerce add-to-cart form because only the relevant attributes for the product variation are removed, not the entire form.
But in our case, if it is desirable to show a "product unavailable" message or something like that, there is no straightforward way to do so. It should be possible to use hook_entity_view_alter() or hook_preprocess_commerce_product_variation() to test the variation state and alter the render array to output a message, but I have not tested this.
@wassper proposed providing a form wrapper template, with appropriate twig variables to determine the state of the form.
Comments
Comment #2
zenimagine commentedWhen I disable the variations of a product and I am on the product page, the following error is displayed :
TypeError: Argument 2 passed to Drupal\commerce_product\ProductVariationFieldRenderer::renderField() must implement interface Drupal\commerce_product\Entity\ProductVariationInterface, null given, called in /home/www.s1biose.com/public_html/web/modules/contrib/commerce/modules/product/src/Plugin/DsField/ProductVariationField.php on line 33 in Drupal\commerce_product\ProductVariationFieldRenderer->renderField() (line 79 of /home/www.s1biose.com/public_html/web/modules/contrib/commerce/modules/product/src/ProductVariationFieldRenderer.php) #0 /home/www.s1biose.com/public_html/web/modules/contrib/commerce/modules/product/src/Plugin/DsField/ProductVariationField.php(33): Drupal\commerce_product\ProductVariationFieldRenderer->renderField('sku', NULL, Array) #1 /home/www.s1biose.com/public_html/web/modules/contrib/ds/ds.module(365): Drupal\commerce_product\Plugin\DsField\ProductVariationField->build() #2 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Extension/ModuleHandler.php(501): ds_entity_view_alter(Array, Object(Drupal\commerce_product\Entity\Product), Object(Drupal\Core\Entity\Entity\EntityViewDisplay)) #3 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Entity/EntityViewBuilder.php(285): Drupal\Core\Extension\ModuleHandler->alter('commerce_produc...', Array, Object(Drupal\commerce_product\Entity\Product), Object(Drupal\Core\Entity\Entity\EntityViewDisplay)) #4 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Entity/EntityViewBuilder.php(220): Drupal\Core\Entity\EntityViewBuilder->buildMultiple(Array) #5 [internal function]: Drupal\Core\Entity\EntityViewBuilder->build(Array) #6 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Render/Renderer.php(376): call_user_func(Array, Array) #7 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Render/Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #8 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(226): Drupal\Core\Render\Renderer->render(Array, false) #9 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() #10 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(227): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #11 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(117): Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #12 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #13 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #14 /home/www.s1biose.com/public_html/vendor/symfony/http-kernel/HttpKernel.php(149): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent)) #15 /home/www.s1biose.com/public_html/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #16 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #17 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #18 /home/www.s1biose.com/public_html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #19 /home/www.s1biose.com/public_html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #20 /home/www.s1biose.com/public_html/web/core/modules/ban/src/BanMiddleware.php(50): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #21 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\ban\BanMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #22 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #23 /home/www.s1biose.com/public_html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #24 /home/www.s1biose.com/public_html/web/core/lib/Drupal/Core/DrupalKernel.php(656): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #25 /home/www.s1biose.com/public_html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #26 {main}.Comment #3
johnpitcairn commentedLooks like a Display Suite issue?
Comment #4
zenimagine commentedThank you, indeed I had applied the following patch :
https://www.drupal.org/files/issues/2723689-3-add-ds-integration.patch
When I delete it, it works.
Thank you, indeed I had applied the following patch:
When I delete it, it works.
But I still have the same problem with the price and the reference that does not show up. I never succeeded in resolving this.
Commerce 2 is really very complicated.
I use "Display Suite" for displaying product pages.
I copied the file "bs-2col-stacked--commerce-product.html.twig" into the templates folder of my theme.
Here are contents :
What should I do ?
I also encounter problems with views and product variations.
It's a nightmare.
Thank you
Comment #5
johnpitcairn commentedSorry, your support request is not relevant to this module.
The problem with the patch should be reported in the issue that provided the patch, and your other support questions should be asked in the forums or in the main commerce issue queue.
Please do not post commerce configuration or support questions in this module's issue queue.
Comment #6
waspper commentedI think providing a way to display needed information could be very useful. But first, we could decide how and what to theme. Here, some points/ideas:
1. Using a global wrapper template (this will wrap the form or the "Out of stock" message), with needed variables. This could allow using same template for several view modes, instead theming each view mode to know the status (if needed/possible), and allowing themers to know if form is enabled/disabled at top of the element.
2. Keeping default form as it's being used currently (no changes). but show a themed output only when variation is disabled. Same as previous: Allowing to theme per view_mode (if needed/possible).
3. Using a different theme for each case: if form and if disabled. Both cases they should provide needed variables, and the output must be as simple as possible.
4. More ideas? :)
Cheers.
Comment #7
johnpitcairn commented@wassper: If/when the field is refactored as a computed field, that will likely be a breaking change anyway, so version 2.0, and we can use a global wrapper then. For now I think option #2 is preferable, to avoid breaking any existing css or javascript that does not expect the form to be wrapped. Working on it.
Comment #8
johnpitcairn commentedLet's try this.
Comment #9
johnpitcairn commentedOops, mismatch on the theme/template name. I don't think we need to use "field" as a prefix. This one should be good.
Comment #10
johnpitcairn commentedComment #11
johnpitcairn commentedComment #12
waspper commentedLast patch is working fine. I've added some improvements, to allow theming by product bundle, variation bundle and view mode. Added theming description into the README.md.
It should cover at least most of cases related to display "XYZ" message or another, depending context.
Cheers.
Comment #14
johnpitcairn commented