Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Add a compatibility layer to keep extensions continue working with Blockified Archive Templates #8172

Merged
merged 11 commits into from Jan 20, 2023

Conversation

dinhtungdu
Copy link
Member

@dinhtungdu dinhtungdu commented Jan 12, 2023

Fixes #8065

This PR adds a new class that acts as the compatibility layer for blockified archive templates by:

  • Injecting custom attribute for the Products block that inherits query from template and its inner blocks.
  • Filtering the output of those inner block, appendding/prepending the corresponding hooks to each blocks.
  • Remove the default callbacks added to those hooks by WooCommerce.

The compatibility is building around Products block because loop is the main element of archive templates and hooks are placing inside and around the loop.

This PR skips these hooks:

  • woocommerce_show_page_title
  • woocommerce_archive_description
  • woocommerce_sidebar

Accessibility

Other Checks

  • This PR adds/removes a feature flag & I've updated this doc.
  • This PR adds/removes an experimental interfaces and I've updated this doc.
  • I tagged two reviewers because this PR makes queries to the database or I think it might have some security impact.

Testing

Automated Tests

  • Changes in this PR are covered by Automated Tests.
    • Unit tests
    • E2E tests

User Facing Testing

  1. Run composer dump-autoload.
  2. Ensure the test site uses a block theme.
  3. Edit the Product Catalog template.
  4. Remove the Classic Template block, and replace it with Products (Beta) block.
  5. Enable Inherit query from template.
  6. Save changes.
  7. Go to the shop page on the front end, see the block works as expected.
  8. In the theme functions.php file, add this snippet, then reload the shop page on the front end to see if the test content is displayed at the expected position:
add_action( 'woocommerce_before_shop_loop_item' , function () {
	echo 'Hook: woocommerce_before_shop_loop_item';
});

image

Repeat for other hooks:

  • woocommerce_before_main_content
  • woocommerce_after_main_content
  • woocommerce_before_shop_loop_item_title
  • woocommerce_shop_loop_item_title
  • woocommerce_after_shop_loop_item_title
  • woocommerce_before_shop_loop_item
  • woocommerce_after_shop_loop_item
  • woocommerce_before_shop_loop
  • woocommerce_after_shop_loop
  • woocommerce_no_products_found
  • Do not include in the Testing Notes

WooCommerce Visibility

  • WooCommerce Core
  • Feature plugin
  • Experimental

Performance Impact

Changelog

Enhancement: Add a compatibility layer to keep extensions continue working with Blockified Archive Templates.

@dinhtungdu dinhtungdu self-assigned this Jan 12, 2023
@dinhtungdu dinhtungdu added focus: FSE Work related to prepare WooCommerce for FSE. focus: template Related to API powering block template functionality in the Site Editor status: needs review labels Jan 12, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Jan 12, 2023

The release ZIP for this PR is accessible via:

https://wcblocks.wpcomstaging.com/wp-content/uploads/woocommerce-gutenberg-products-block-8172.zip

Script Dependencies Report

The compare-assets action has detected some changed script dependencies between this branch and trunk. Please review and confirm the following are correct before merging.

Script Handle Added Removed
reviews-frontend.js react, wc-settings, wp-a11y, wp-api-fetch, wp-compose, wp-element, wp-i18n, wp-is-shallow-equal, wp-polyfill ⚠️
active-filters-frontend.js lodash, react, wc-blocks-data-store, wc-price-format, wc-settings, wp-data, wp-element, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-polyfill, wp-primitives, wp-url ⚠️
all-products-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-blocks-registry, wc-blocks-shared-context, wc-blocks-shared-hocs, wc-price-format, wc-settings, wp-a11y, wp-api-fetch, wp-autop, wp-block-editor, wp-blocks, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-hooks, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-polyfill, wp-primitives, wp-url, wp-warning, wp-wordcount ⚠️
attribute-filter-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-settings, wp-a11y, wp-block-editor, wp-blocks, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-keycodes, wp-polyfill, wp-primitives, wp-url, wp-warning ⚠️
cart-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-blocks-registry, wc-blocks-shared-context, wc-blocks-shared-hocs, wc-price-format, wc-settings, wp-a11y, wp-api-fetch, wp-autop, wp-block-editor, wp-blocks, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-hooks, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-keycodes, wp-plugins, wp-polyfill, wp-primitives, wp-url, wp-warning, wp-wordcount ⚠️
checkout-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-blocks-registry, wc-blocks-shared-hocs, wc-price-format, wc-settings, wp-a11y, wp-api-fetch, wp-autop, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-hooks, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-keycodes, wp-plugins, wp-polyfill, wp-primitives, wp-url, wp-warning, wp-wordcount ⚠️
filter-wrapper-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-blocks-registry, wc-price-format, wc-settings, wp-a11y, wp-block-editor, wp-blocks, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-keycodes, wp-polyfill, wp-primitives, wp-url, wp-warning ⚠️
mini-cart-frontend.js wc-settings, wp-polyfill ⚠️
price-filter-frontend.js lodash, react, wc-blocks-data-store, wc-price-format, wc-settings, wp-data, wp-element, wp-i18n, wp-is-shallow-equal, wp-polyfill, wp-url ⚠️
rating-filter-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-settings, wp-a11y, wp-block-editor, wp-blocks, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-i18n, wp-is-shallow-equal, wp-keycodes, wp-polyfill, wp-primitives, wp-url, wp-warning ⚠️
single-product-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-blocks-registry, wc-blocks-shared-context, wc-blocks-shared-hocs, wc-price-format, wc-settings, wp-api-fetch, wp-autop, wp-block-editor, wp-blocks, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-hooks, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-polyfill, wp-primitives, wp-url, wp-warning, wp-wordcount ⚠️
stock-filter-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-settings, wp-a11y, wp-block-editor, wp-blocks, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-keycodes, wp-polyfill, wp-primitives, wp-url, wp-warning ⚠️
mini-cart-component-frontend.js lodash, react, wc-blocks-checkout, wc-blocks-data-store, wc-blocks-registry, wc-price-format, wc-settings, wp-a11y, wp-autop, wp-compose, wp-data, wp-deprecated, wp-dom, wp-element, wp-hooks, wp-html-entities, wp-i18n, wp-is-shallow-equal, wp-keycodes, wp-polyfill, wp-primitives, wp-url, wp-warning, wp-wordcount ⚠️

This comment was automatically generated by the ./github/compare-assets action.

TypeScript Errors Report

  • Files with errors: 496
  • Total errors: 2250

🎉 🎉 This PR does not introduce new TS errors.

comments-aggregator

@github-actions
Copy link
Contributor

github-actions bot commented Jan 12, 2023

Size Change: 0 B

Total Size: 1.08 MB

ℹ️ View Unchanged
Filename Size
build/active-filters-frontend.js 7.99 kB
build/active-filters-wrapper-frontend.js 6.01 kB
build/active-filters.js 7.31 kB
build/all-products-frontend.js 11.6 kB
build/all-products.js 33.4 kB
build/all-reviews.js 7.67 kB
build/attribute-filter-frontend.js 22.9 kB
build/attribute-filter-wrapper-frontend.js 7.68 kB
build/attribute-filter.js 12.4 kB
build/blocks-checkout.js 41 kB
build/cart-blocks/cart-accepted-payment-methods-frontend.js 1.38 kB
build/cart-blocks/cart-cross-sells-frontend.js 253 B
build/cart-blocks/cart-cross-sells-products-frontend.js 9.61 kB
build/cart-blocks/cart-express-payment--checkout-blocks/express-payment-frontend.js 5.08 kB
build/cart-blocks/cart-express-payment-frontend.js 722 B
build/cart-blocks/cart-items-frontend.js 299 B
build/cart-blocks/cart-line-items--mini-cart-contents-block/products-table-frontend.js 5.33 kB
build/cart-blocks/cart-line-items-frontend.js 1.07 kB
build/cart-blocks/cart-order-summary-frontend.js 1.25 kB
build/cart-blocks/cart-totals-frontend.js 321 B
build/cart-blocks/empty-cart-frontend.js 345 B
build/cart-blocks/filled-cart-frontend.js 656 B
build/cart-blocks/order-summary-coupon-form-frontend.js 1.69 kB
build/cart-blocks/order-summary-discount-frontend.js 2.12 kB
build/cart-blocks/order-summary-fee-frontend.js 274 B
build/cart-blocks/order-summary-heading-frontend.js 456 B
build/cart-blocks/order-summary-shipping-frontend.js 14.9 kB
build/cart-blocks/order-summary-subtotal-frontend.js 274 B
build/cart-blocks/order-summary-taxes-frontend.js 435 B
build/cart-blocks/proceed-to-checkout-frontend.js 1.24 kB
build/cart-frontend.js 28.5 kB
build/cart.js 47.5 kB
build/catalog-sorting.js 1.71 kB
build/checkout-blocks/actions-frontend.js 1.85 kB
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 3.91 kB
build/checkout-blocks/billing-address-frontend.js 1.15 kB
build/checkout-blocks/contact-information-frontend.js 2.04 kB
build/checkout-blocks/express-payment-frontend.js 1.13 kB
build/checkout-blocks/fields-frontend.js 344 B
build/checkout-blocks/order-note-frontend.js 1.14 kB
build/checkout-blocks/order-summary-cart-items-frontend.js 3.67 kB
build/checkout-blocks/order-summary-coupon-form-frontend.js 1.85 kB
build/checkout-blocks/order-summary-discount-frontend.js 2.29 kB
build/checkout-blocks/order-summary-fee-frontend.js 277 B
build/checkout-blocks/order-summary-frontend.js 1.25 kB
build/checkout-blocks/order-summary-shipping-frontend.js 14.9 kB
build/checkout-blocks/order-summary-subtotal-frontend.js 275 B
build/checkout-blocks/order-summary-taxes-frontend.js 435 B
build/checkout-blocks/payment-frontend.js 8.33 kB
build/checkout-blocks/pickup-options-frontend.js 2.78 kB
build/checkout-blocks/shipping-address-frontend.js 1.11 kB
build/checkout-blocks/shipping-method-frontend.js 2.26 kB
build/checkout-blocks/shipping-methods-frontend.js 4.83 kB
build/checkout-blocks/terms-frontend.js 1.56 kB
build/checkout-blocks/totals-frontend.js 324 B
build/checkout-frontend.js 30.1 kB
build/checkout.js 43.3 kB
build/customer-account.js 3.08 kB
build/featured-category.js 13.1 kB
build/featured-product.js 13.4 kB
build/filter-wrapper-frontend.js 14.1 kB
build/filter-wrapper.js 2.4 kB
build/general-style-rtl.css 1.31 kB
build/general-style.css 1.31 kB
build/handpicked-products.js 7.24 kB
build/legacy-template.js 2.87 kB
build/mini-cart-component-frontend.js 27.7 kB
build/mini-cart-contents-block/empty-cart-frontend.js 366 B
build/mini-cart-contents-block/filled-cart-frontend.js 268 B
build/mini-cart-contents-block/footer-frontend.js 2.82 kB
build/mini-cart-contents-block/items-frontend.js 237 B
build/mini-cart-contents-block/products-table-frontend.js 590 B
build/mini-cart-contents-block/shopping-button-frontend.js 313 B
build/mini-cart-contents-block/title-frontend.js 367 B
build/mini-cart-contents.js 16.9 kB
build/mini-cart-frontend.js 1.88 kB
build/mini-cart.js 4.29 kB
build/price-filter-frontend.js 13.9 kB
build/price-filter-wrapper-frontend.js 7.01 kB
build/price-filter.js 8.4 kB
build/price-format.js 1.19 kB
build/product-add-to-cart--product-button--product-category-list--product-image--product-price--product-r--a0326d00.js 226 B
build/product-add-to-cart--product-button--product-image--product-rating--product-title.js 151 B
build/product-add-to-cart-frontend.js 6.71 kB
build/product-add-to-cart.js 8.47 kB
build/product-best-sellers.js 7.61 kB
build/product-button--product-category-list--product-image--product-price--product-rating--product-sale-b--e17c7c01.js 439 B
build/product-button--product-image--product-rating--product-sale-badge--product-title.js 257 B
build/product-button-frontend.js 2.14 kB
build/product-button.js 3.84 kB
build/product-categories.js 2.36 kB
build/product-category-list-frontend.js 1.14 kB
build/product-category-list.js 503 B
build/product-category.js 8.6 kB
build/product-image-frontend.js 2.14 kB
build/product-image.js 3.94 kB
build/product-new.js 7.6 kB
build/product-on-sale.js 7.93 kB
build/product-price-frontend.js 2.18 kB
build/product-price.js 1.54 kB
build/product-query.js 5.95 kB
build/product-rating-frontend.js 1.57 kB
build/product-rating.js 920 B
build/product-results-count.js 1.68 kB
build/product-sale-badge-frontend.js 1.37 kB
build/product-sale-badge.js 812 B
build/product-search.js 2.62 kB
build/product-sku-frontend.js 629 B
build/product-sku.js 377 B
build/product-stock-indicator-frontend.js 1.26 kB
build/product-stock-indicator.js 645 B
build/product-summary-frontend.js 1.53 kB
build/product-summary.js 920 B
build/product-tag-list-frontend.js 1.13 kB
build/product-tag-list.js 496 B
build/product-tag.js 8.08 kB
build/product-title-frontend.js 1.57 kB
build/product-title.js 3.31 kB
build/product-top-rated.js 7.84 kB
build/products-by-attribute.js 8.52 kB
build/rating-filter-frontend.js 21.4 kB
build/rating-filter-wrapper-frontend.js 6.21 kB
build/rating-filter.js 7.43 kB
build/reviews-by-category.js 11.2 kB
build/reviews-by-product.js 12.3 kB
build/reviews-frontend.js 7.14 kB
build/single-product-frontend.js 17.7 kB
build/single-product.js 9.99 kB
build/stock-filter-frontend.js 21.1 kB
build/stock-filter-wrapper-frontend.js 5.87 kB
build/stock-filter.js 8.17 kB
build/store-notices.js 1.64 kB
build/vendors--attribute-filter-wrapper--cart-blocks/cart-cross-sells-products--cart-blocks/order-summary--82e4ed06-frontend.js 6.86 kB
build/vendors--attribute-filter-wrapper--rating-filter-wrapper--stock-filter-wrapper-frontend.js 7.7 kB
build/vendors--cart-blocks/cart-cross-sells-products--cart-blocks/cart-line-items--cart-blocks/cart-order--3c5fe802-frontend.js 5.26 kB
build/vendors--cart-blocks/cart-cross-sells-products--cart-blocks/order-summary-shipping--checkout-blocks--18f9376a-frontend.js 19.4 kB
build/vendors--cart-blocks/cart-cross-sells-products--product-add-to-cart-frontend.js 7.53 kB
build/vendors--cart-blocks/cart-line-items--checkout-blocks/order-summary-cart-items--mini-cart-contents---233ab542-frontend.js 3.14 kB
build/vendors--cart-blocks/order-summary-shipping--checkout-blocks/billing-address--checkout-blocks/order--5b8feb0b-frontend.js 4.83 kB
build/vendors--checkout-blocks/shipping-method-frontend.js 12 kB
build/vendors--checkout-blocks/shipping-methods-frontend.js 9.48 kB
build/wc-blocks-data.js 21.6 kB
build/wc-blocks-editor-style-rtl.css 5.41 kB
build/wc-blocks-editor-style.css 5.41 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 933 B
build/wc-blocks-registry.js 3.16 kB
build/wc-blocks-shared-context.js 1.52 kB
build/wc-blocks-shared-hocs.js 1.73 kB
build/wc-blocks-style-rtl.css 25.6 kB
build/wc-blocks-style.css 25.6 kB
build/wc-blocks-vendors-style-rtl.css 1.96 kB
build/wc-blocks-vendors-style.css 1.96 kB
build/wc-blocks-vendors.js 64.2 kB
build/wc-blocks.js 2.63 kB
build/wc-payment-method-bacs.js 816 B
build/wc-payment-method-cheque.js 811 B
build/wc-payment-method-cod.js 909 B
build/wc-payment-method-paypal.js 837 B
build/wc-settings.js 2.6 kB
build/wc-shipping-method-pickup-location.js 29.7 kB

compressed-size-action

@dinhtungdu dinhtungdu marked this pull request as ready for review January 12, 2023 16:21
@woocommercebot woocommercebot requested review from a team and danieldudzic and removed request for a team January 12, 2023 16:21
@dinhtungdu dinhtungdu changed the title wip: initial BlockTemplatesCompatibility class Add a compatibility layer to keep extensions continue working with Blockified Archive Templates Jan 12, 2023
Copy link
Contributor

@nerrad nerrad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direction is looking good. I just have a couple comments that impact mergeability.

src/Templates/BlockTemplatesCompatibility.php Outdated Show resolved Hide resolved
src/Templates/BlockTemplatesCompatibility.php Outdated Show resolved Hide resolved
Copy link
Contributor

@Aljullu Aljullu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, @dinhtungdu! 👏 I left some comments inline but overall looking good.

src/Templates/BlockTemplatesCompatibility.php Outdated Show resolved Hide resolved
),
),
'core/query-no-results' => array(
'woocommerce_no_products_found' => array(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woocommerce_no_products_found seems to be triggered even if there are products in the loop:

imatge

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I noticed the same issue.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this issue by checking the block content before injecting the hooks.

src/Templates/BlockTemplatesCompatibility.php Outdated Show resolved Hide resolved
@gigitux
Copy link
Contributor

gigitux commented Jan 16, 2023

Great work, Tung!
Besides the comments that other folks are added, I have nothing to say 💪

@dinhtungdu
Copy link
Member Author

@nerrad @Aljullu @gigitux I addressed your feedback, can you please give this PR another review? Thank you so much!

Comment on lines 105 to 129
if ( empty( $block_content ) ) {
return $block_content;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this mean the woocommerce_no_products_found won't fire?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the actions fire only when blocks return non-empty content. For the core/query-no-results case, when the query has products, the block content will be empty, then woocommerce_no_products_found shouldn't be fired.

But this will be false positive if we remove all inner blocks from core/query-no-results. We need a second thought on this 🤔 .

*
* @param array $hook_data Hook data.
*/
return apply_filters( 'woocommerce_blocks_hooks_compatibility_data', $hook_data );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should preserve the original hook data instead of allowing it to be overwritten by the filter? that would reduce the ability for extensions to muck things up accidentally? It'd also mean the shape of the data can be validated before passing on to callers.

I'm on the fence about whether we should just provide a registration mechanism for these to make it easier for extensions to register additional items (especially given it'd be easy to mess up the array). What has me thinking to stick with the filter is the likelihood of it getting used much.

Comment on lines 204 to 208
/**
* Filter the hook data used to replace the default WooCommerce hooks.
*
* @param array $hook_data Hook data.
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the complexity of the hook data array, it'd be good to expand on the doc block a bit more about its shape.

@dinhtungdu
Copy link
Member Author

dinhtungdu commented Jan 17, 2023

In bccfa1a, I refactored the hook data structure to reduce the depth of the array as well as make it easier to manipulate the data inside the class.

For the filter, I limited the data developer can pass to the filter to make it safer and easier to use. Instead of letting developer change the all hook data, now we only allow them to add new hooked functions to the supported hooks. Can you take another look at this @nerrad? Thank you.

Copy link
Contributor

@nerrad nerrad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the back and forth but I have a couple more feedback pieces.

src/Templates/BlockTemplatesCompatibility.php Outdated Show resolved Hide resolved
src/Templates/BlockTemplatesCompatibility.php Outdated Show resolved Hide resolved
return;
}

foreach ( $additional_hook_data as $data ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should make sure $additional_data is an array before treating it as one here. Extensions could muck up the type so let's validate first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed in 1cdcd5c.

@Aljullu Aljullu requested a review from nerrad January 19, 2023 11:59
Copy link
Contributor

@nerrad nerrad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻 Code-wise things look good. I haven't tested.

@Aljullu Aljullu force-pushed the add/archive-template-compatibility-layer branch from 1cdcd5c to 0765a73 Compare January 20, 2023 10:42
@Aljullu
Copy link
Contributor

Aljullu commented Jan 20, 2023

I did a last round of testing and everything is looking good on my side. There are some e2e tests failing, but they are failing in trunk too and don't seem to be related to this PR.

@Aljullu Aljullu merged commit fc42092 into trunk Jan 20, 2023
@Aljullu Aljullu deleted the add/archive-template-compatibility-layer branch January 20, 2023 11:44
@nielslange nielslange added the type: enhancement The issue is a request for an enhancement. label Jan 30, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
focus: FSE Work related to prepare WooCommerce for FSE. focus: template Related to API powering block template functionality in the Site Editor type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement the compatibility layer for blockified archive templates.
5 participants