Commit 95395451d55 for woocommerce
commit 95395451d55afdd200e21bfc962de6c421981974
Author: Luigi Teschio <gigitux@gmail.com>
Date: Fri Sep 18 14:42:41 2026 +0200
Hide incompatible WooCommerce template parts in the inserter (#68856)
* Fix incompatible template parts appearing in the inserter
* Add changelog for template part inserter fix
* Improve E2E test
* fix selector
* fix E2E test
* fix logic
diff --git a/plugins/woocommerce/changelog/fix-hide-incompatible-template-parts b/plugins/woocommerce/changelog/fix-hide-incompatible-template-parts
new file mode 100644
index 00000000000..339efa282c9
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-hide-incompatible-template-parts
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Hide Mini Cart and Add to Cart with Options template parts from the block inserter, including instance variations.
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/index.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/index.tsx
index 0040333b435..97a1cb64b90 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/index.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/index.tsx
@@ -5,7 +5,6 @@ import { button } from '@wordpress/icons';
import { getPlugin, registerPlugin } from '@wordpress/plugins';
import { registerProductBlockType } from '@woocommerce/atomic-utils';
import type { BlockConfiguration } from '@wordpress/blocks';
-import { addFilter } from '@wordpress/hooks';
/**
* Internal dependencies
@@ -46,30 +45,3 @@ registerProductBlockType< Attributes >(
isAvailableOnPostEditor: true,
}
);
-
-// Remove the Add to Cart + Options template part from the block inserter.
-addFilter(
- 'blocks.registerBlockType',
- 'woocommerce/area_add-to-cart-with-options',
- function ( blockSettings, blockName ) {
- if ( blockName === 'core/template-part' ) {
- return {
- ...blockSettings,
- variations: blockSettings.variations.map(
- ( variation: { name: string } ) => {
- if (
- variation.name === 'area_add-to-cart-with-options'
- ) {
- return {
- ...variation,
- scope: [],
- };
- }
- return variation;
- }
- ),
- };
- }
- return blockSettings;
- }
-);
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/index.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/index.tsx
index 2701681464a..d2f0fb709f2 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/index.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/index.tsx
@@ -4,7 +4,6 @@
import { miniCartAlt } from '@woocommerce/icons';
import { Icon } from '@wordpress/icons';
import { registerBlockType } from '@wordpress/blocks';
-import { addFilter } from '@wordpress/hooks';
/**
* Internal dependencies
*/
@@ -44,28 +43,3 @@ registerBlockType( metadata, {
return null;
},
} );
-
-// Remove the Mini Cart template part from the block inserter.
-addFilter(
- 'blocks.registerBlockType',
- 'woocommerce/area_mini-cart',
- function ( blockSettings, blockName ) {
- if ( blockName === 'core/template-part' ) {
- return {
- ...blockSettings,
- variations: blockSettings.variations.map(
- ( variation: { name: string } ) => {
- if ( variation.name === 'area_mini-cart' ) {
- return {
- ...variation,
- scope: [],
- };
- }
- return variation;
- }
- ),
- };
- }
- return blockSettings;
- }
-);
diff --git a/plugins/woocommerce/client/blocks/assets/js/filters/hide-incompatible-template-parts.ts b/plugins/woocommerce/client/blocks/assets/js/filters/hide-incompatible-template-parts.ts
new file mode 100644
index 00000000000..811d8107439
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/filters/hide-incompatible-template-parts.ts
@@ -0,0 +1,46 @@
+/**
+ * External dependencies
+ */
+import type { BlockVariation } from '@wordpress/blocks';
+import { addFilter } from '@wordpress/hooks';
+
+// These areas require their owning WooCommerce block to render correctly.
+const INCOMPATIBLE_TEMPLATE_PART_AREAS = [
+ 'mini-cart',
+ 'add-to-cart-with-options',
+];
+
+addFilter(
+ 'blocks.registerBlockType',
+ 'woocommerce/hide-incompatible-template-parts',
+ (
+ blockSettings: { variations?: BlockVariation< { area?: string } >[] },
+ blockName: string
+ ) => {
+ if (
+ blockName !== 'core/template-part' ||
+ ! blockSettings.variations
+ ) {
+ return blockSettings;
+ }
+
+ return {
+ ...blockSettings,
+ variations: blockSettings.variations.map( ( variation ) => {
+ if (
+ INCOMPATIBLE_TEMPLATE_PART_AREAS.includes(
+ variation.attributes?.area ?? ''
+ )
+ ) {
+ return {
+ ...variation,
+ scope: ( variation.scope ?? [] ).filter(
+ ( scope ) => scope !== 'inserter'
+ ),
+ };
+ }
+ return variation;
+ } ),
+ };
+ }
+);
diff --git a/plugins/woocommerce/client/blocks/assets/js/index.js b/plugins/woocommerce/client/blocks/assets/js/index.js
index d481cda11f1..28ae6325465 100644
--- a/plugins/woocommerce/client/blocks/assets/js/index.js
+++ b/plugins/woocommerce/client/blocks/assets/js/index.js
@@ -5,5 +5,6 @@ import '../css/editor.scss';
import '../css/style.scss';
import './filters/block-list-block';
import './filters/get-block-attributes';
+import './filters/hide-incompatible-template-parts';
import './filters/unregister-block-types';
import './base/components/notice-banner/style.scss';
diff --git a/plugins/woocommerce/tests/e2e/tests/site-editor/template-parts-inserter.spec.ts b/plugins/woocommerce/tests/e2e/tests/site-editor/template-parts-inserter.spec.ts
new file mode 100644
index 00000000000..56171165a90
--- /dev/null
+++ b/plugins/woocommerce/tests/e2e/tests/site-editor/template-parts-inserter.spec.ts
@@ -0,0 +1,65 @@
+/**
+ * External dependencies
+ */
+import { Admin, Editor, PageUtils } from '@wordpress/e2e-test-utils-playwright';
+
+/**
+ * Internal dependencies
+ */
+import { test, expect } from '../../fixtures/fixtures';
+import { ADMIN_STATE_PATH } from '../../playwright.config';
+
+test.use( { storageState: ADMIN_STATE_PATH } );
+
+test.describe( 'Template parts in the Site Editor inserter', () => {
+ test( 'shows only compatible template parts', async ( { page } ) => {
+ const editor = new Editor( { page } );
+ const admin = new Admin( {
+ page,
+ editor,
+ pageUtils: new PageUtils( { page } ),
+ } );
+ await admin.visitSiteEditor( { canvas: 'edit' } );
+ await page
+ .getByRole( 'button', { name: 'Block Inserter', exact: true } )
+ .click();
+
+ await test.step( 'can insert a template part not related to Mini-Cart and Add to Cart + Options', async () => {
+ await page
+ .getByRole( 'searchbox', { name: 'Search' } )
+ .fill( 'Footer' );
+
+ await expect(
+ page.locator( '.editor-block-list-item-template-part' )
+ ).toBeVisible();
+ } );
+
+ await test.step( "can't insert the Mini Cart template part", async () => {
+ await page
+ .getByRole( 'searchbox', { name: 'Search' } )
+ .fill( 'Mini-Cart' );
+ const miniCart = page
+ .getByRole( 'listbox', { name: 'Blocks', exact: true } )
+ .getByRole( 'option', { name: 'Mini-Cart', exact: true } );
+ await expect( miniCart ).toHaveCount( 1 );
+ await expect( miniCart ).toBeVisible();
+ } );
+
+ await test.step( 'hides the Add to Cart + Options template parts', async () => {
+ for ( const productType of [
+ 'Simple',
+ 'Variable',
+ 'Grouped',
+ 'External',
+ ] ) {
+ const title = `${ productType } Product Add to Cart + Options`;
+ await page
+ .getByRole( 'searchbox', { name: 'Search' } )
+ .fill( title );
+ await expect(
+ page.getByRole( 'option', { name: title, exact: true } )
+ ).toHaveCount( 0 );
+ }
+ } );
+ } );
+} );