From e54ec547668d09d667d035cc3e24817fffb269d6 Mon Sep 17 00:00:00 2001 From: boo-code Date: Sat, 5 Sep 2026 12:23:08 +0200 Subject: [PATCH] Drop the Product Details tab when it has nothing to show Every block in product-details.tpl is conditional except product_out_of_stock, which emitted its wrapper even when no module answered actionProductOutOfStock. A product with no manufacturer, no reference, hidden quantities, no availability date, no features, no specific references and no condition therefore produced a Product Details tab whose whole content was one empty div - and the tab itself was rendered unconditionally, unlike Description and Attachments which are both guarded. The out-of-stock block is now guarded the way its six siblings are, and the partial publishes whether it has any content so product.tpl can drop the nav item too. When there is no description the pane is kept even when empty, because it is the one carrying `active`. The decision travels as a variable rather than as "is the rendered include empty": in debug mode SmartyDevTemplate wraps every include in comments, so a caller testing the markup would find it non-empty on every dev shop. --- .../catalog/_partials/product-details.tpl | 40 ++++++++++++++----- templates/catalog/product.tpl | 31 ++++++++------ 2 files changed, 50 insertions(+), 21 deletions(-) diff --git a/templates/catalog/_partials/product-details.tpl b/templates/catalog/_partials/product-details.tpl index df4deb8b..4e3b4622 100644 --- a/templates/catalog/_partials/product-details.tpl +++ b/templates/catalog/_partials/product-details.tpl @@ -1,8 +1,7 @@ -
+{* Every block below is conditional, so the pane can come out with nothing in it. Capture it first and + emit the wrapper only when it holds something, so product.tpl can drop the tab instead of showing an + empty panel. Child themes overriding any block are unaffected - the blocks are unchanged. *} +{capture name='product_details_content'} {block name='product_reference'} {if !empty($product_manufacturer.id)}
@@ -55,9 +54,14 @@ {/block} {block name='product_out_of_stock'} -
- {hook h='actionProductOutOfStock' product=$product} -
+ {* The six sibling blocks all guard their markup; this one emitted its wrapper even when no module + answered the hook, which is what left the pane holding a single empty div. *} + {capture name='product_out_of_stock'}{hook h='actionProductOutOfStock' product=$product}{/capture} + {if trim($smarty.capture.product_out_of_stock) !== ''} +
+ {$smarty.capture.product_out_of_stock nofilter} +
+ {/if} {/block} {block name='product_features'} @@ -98,4 +102,22 @@
{/if} {/block} -
+{/capture} + +{* Keep the pane when it has content. When it has none it is only kept if there is no description tab, + because then this pane is the one carrying `active` and something has to be shown. + + The answer is published as a variable rather than left for the caller to infer from this template's + output: in debug mode SmartyDevTemplate wraps every include in `` comments, so a + caller testing the rendered markup for emptiness would find it non-empty on every dev shop. *} +{assign var='product_details_has_content' value=(trim($smarty.capture.product_details_content) !== '') scope='root'} + +{if $product_details_has_content || !$product.description} +
+ {$smarty.capture.product_details_content nofilter} +
+{/if} diff --git a/templates/catalog/product.tpl b/templates/catalog/product.tpl index 6693eaac..f2928515 100644 --- a/templates/catalog/product.tpl +++ b/templates/catalog/product.tpl @@ -139,6 +139,13 @@ {/block} {block name='product_tabs'} + {* Rendered up front so the nav can tell whether the Product Details tab has anything to show. + The partial decides that itself and returns nothing when it does not. *} + {capture name='product_details_pane'} + {block name='product_details'} + {include file='catalog/_partials/product-details.tpl'} + {/block} + {/capture}