This issue is automatically created based on existing pull request: #41171: Namespace related/up-sell item ids so the blocks stop hiding each other (#37482)
Description
When the same product is assigned as both a Related Product and an Up-Sell Product, the two blocks fight over each other's visibility: an item shown in one block disappears from the other.
app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml renders every related and up-sell item with an id derived only from the product:
id="product-item_<?= $_item->getId() ?>"
and then emits a hide rule through $secureRenderer->renderStyleAsTag('display:none;', 'li#product-item_' . $_item->getId()).
Two consequences, both present on current 2.4-develop:
- The same product rendered in both blocks produces duplicate DOM ids, which is invalid HTML.
- The emitted style rule is document-global. When the related block's limit/shuffle logic hides its own entry, the selector also matches the up-sell block's
<li> for that product, and vice versa.
The fix namespaces the id by block type, so each block gets its own element and its own selector.
This PR continues #37482 by @igorwulff (Partner: Youwe), rebased onto current 2.4-develop. Their commit and authorship are preserved.
Fixed Issues
No linked issue on the original PR; the defect is described above and is reproducible on current 2.4-develop.
Manual testing scenarios
- Create product A and product B.
- On product A, assign product B as both a Related Product and an Up-Sell Product. Save.
- Open product A on the storefront.
- Before: product B appears in only one of the two blocks — the other block's entry is hidden by the shared style rule. Inspecting the DOM shows two elements with the same
id="product-item_<B>".
After: product B appears in both blocks, with distinct ids product-item-related_<B> and product-item-upsell_<B>.
Questions or comments
The only feedback ever left on the original PR was @engcom-Hotel asking for automated coverage:
I suggest you to cover the changes with some automated tests like functional tests.
That is what this adds: StorefrontRelatedAndUpsellSharedProductVisibilityTest assigns one product as both a Related and an Up-Sell product, then asserts there is exactly one li#product-item-related_<id> and exactly one li#product-item-upsell_<id>, that nothing matches the old collapsed li#product-item_<id>, and that neither element computes to display: none.
One note on reading that test: under the default configuration there is no item limit on these blocks, so the "both are visible" assertions alone would pass even without the fix. The assertions that actually pin the regression are the id-uniqueness ones and the absence of the legacy id.
Verified locally on 2.4-develop:
- The new MFTF test validates against
testSchema.xsd, and all eight action groups it references exist in core.
git grep confirms the old product-item_<id> id is referenced nowhere else in core — no JS, LESS, CSS or template depends on it, so the rename is self-contained. (The @product-item__hover__* hits in Luma's LESS are unrelated variables.)
The original PR also carried a second commit that rewrote the copyright header and renamed $block->escape* to $escaper->escape*. That was purely cosmetic, conflicted with changes upstream has since made itself, and added nothing to the fix, so it was dropped during the rebase — this PR is limited to the id change.
Contribution checklist
This issue is automatically created based on existing pull request: #41171: Namespace related/up-sell item ids so the blocks stop hiding each other (#37482)
Description
When the same product is assigned as both a Related Product and an Up-Sell Product, the two blocks fight over each other's visibility: an item shown in one block disappears from the other.
app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtmlrenders every related and up-sell item with an id derived only from the product:and then emits a hide rule through
$secureRenderer->renderStyleAsTag('display:none;', 'li#product-item_' . $_item->getId()).Two consequences, both present on current
2.4-develop:<li>for that product, and vice versa.The fix namespaces the id by block type, so each block gets its own element and its own selector.
This PR continues #37482 by @igorwulff (Partner: Youwe), rebased onto current
2.4-develop. Their commit and authorship are preserved.Fixed Issues
No linked issue on the original PR; the defect is described above and is reproducible on current
2.4-develop.Manual testing scenarios
id="product-item_<B>".After: product B appears in both blocks, with distinct ids
product-item-related_<B>andproduct-item-upsell_<B>.Questions or comments
The only feedback ever left on the original PR was @engcom-Hotel asking for automated coverage:
That is what this adds:
StorefrontRelatedAndUpsellSharedProductVisibilityTestassigns one product as both a Related and an Up-Sell product, then asserts there is exactly oneli#product-item-related_<id>and exactly oneli#product-item-upsell_<id>, that nothing matches the old collapsedli#product-item_<id>, and that neither element computes todisplay: none.One note on reading that test: under the default configuration there is no item limit on these blocks, so the "both are visible" assertions alone would pass even without the fix. The assertions that actually pin the regression are the id-uniqueness ones and the absence of the legacy id.
Verified locally on
2.4-develop:testSchema.xsd, and all eight action groups it references exist in core.git grepconfirms the oldproduct-item_<id>id is referenced nowhere else in core — no JS, LESS, CSS or template depends on it, so the rename is self-contained. (The@product-item__hover__*hits in Luma's LESS are unrelated variables.)The original PR also carried a second commit that rewrote the copyright header and renamed
$block->escape*to$escaper->escape*. That was purely cosmetic, conflicted with changes upstream has since made itself, and added nothing to the fix, so it was dropped during the rebase — this PR is limited to the id change.Contribution checklist