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

Conversation

thealexandrelara
Copy link
Contributor

@thealexandrelara thealexandrelara commented Nov 7, 2023

What

  • Add a TemplateChangeDetector that detects when a template or page changes and notifies any subscribers (currently only the BlockRegistrationManager).
  • Add the BlockRegistrationManager, which is responsible for registering/unregistering blocks according to the current template/page.
  • In a subsequent PR, we can replace the current implementation of registerBlockSingleProductTemplate with this new pattern, which is more performant and less prone to racing conditions that have already caused issues in the past.

Fixes #11027

Why

The current implementation of the Product Gallery block does not work outside the Single Product template context (or the Product Gallery template part, which is responsible for the dialog when clicking on the Large Image block). Therefore, we need to restrict the block to be available only within this context.

Testing Instructions

Please consider any edge cases this change may have, and also other areas of the product this may impact.

Test 1: Single Product template

  1. From your WordPress dashboard, go to Appearance > Themes. Select a block-based theme like "Twenty-twenty Three," "Twenty-twenty Four," etc.
  2. On the left-hand side menu, click on Appearance > Editor > Templates
  3. Find and select the 'Single Product' template from the list.
  4. When the Classic Product Template renders, click on Transform into Blocks. This will transform the Classic template in a block template if you haven't done it before.
  5. Inside the Page editor, click on the '+' button to add a new block.
  6. In the block library that pops up, search for the 'Product Gallery' block. Click on it to add the block to the template.
  7. Make sure the Product Gallery block can be added to the editor.
  8. Click on Save.
  9. Visit a product page of a Variable Product and make sure the block is working as expected.

Test 2: Posts

  1. From your WordPress dashboard, go to Appearance > Themes. Select a block-based theme like "Twenty-twenty Three," "Twenty-twenty Four," etc.
  2. On the left-hand side menu, click on Posts > Add new.
  3. Inside the Page editor, click on the '+' button to add a new block.
  4. In the block library that pops up, search for the 'Product Gallery' block.
  5. Make sure the Product Gallery block DOES NOT appear and cannot be added to the editor.

Test 3: Pages

  1. From your WordPress dashboard, go to Appearance > Themes. Select a block-based theme like "Twenty-twenty Three," "Twenty-twenty Four," etc.
  2. On the left-hand side menu, click on Pages > Add new.
  3. Inside the Page editor, click on the '+' button to add a new block.
  4. In the block library that pops up, search for the 'Product Gallery' block.
  5. Make sure the Product Gallery block DOES NOT appear and cannot be added to the editor.
  • Do not include in the Testing Notes
  • Should be tested by the development team exclusively

WooCommerce Visibility

Required:

  • WooCommerce Core
  • Feature plugin
  • Experimental
  • N/A

Copy link
Contributor

github-actions bot commented Nov 7, 2023

The release ZIP for this PR is accessible via:

https://wcblocks.wpcomstaging.com/wp-content/uploads/woocommerce-gutenberg-products-block-11664.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
wc-blocks-style.js wp-block-editor, wp-components, wp-data, wp-dom-ready ⚠️

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

TypeScript Errors Report

  • Files with errors: 575
  • Total errors: 2487

🎉 🎉 This PR does not introduce new TS errors.

comments-aggregator

Copy link
Contributor

github-actions bot commented Nov 7, 2023

Size Change: +6.61 kB (0%)

Total Size: 1.59 MB

Filename Size Change
build/attribute-filter.js 11.3 kB -1 B (0%)
build/cart.js 39.7 kB +2 B (0%)
build/price-filter.js 7.53 kB -2 B (0%)
build/product-gallery-large-image-next-previous.js 4.27 kB +17 B (0%)
build/product-gallery-pager.js 3.48 kB -1 B (0%)
build/product-gallery-thumbnails.js 3.94 kB +39 B (+1%)
build/product-gallery.js 9.6 kB +33 B (0%)
build/wc-blocks.js 9.15 kB +6.52 kB (+248%) 🆘
ℹ️ View Unchanged
Filename Size
build/3810-frontend.js 18.3 kB
build/4124-frontend.js 23.9 kB
build/8280-frontend.js 8.48 kB
build/active-filters-frontend.js 6.69 kB
build/active-filters-rtl.css 1.68 kB
build/active-filters-wrapper-frontend.js 6.9 kB
build/active-filters-wrapper-rtl.css 1.53 kB
build/active-filters-wrapper.css 1.53 kB
build/active-filters.css 1.68 kB
build/active-filters.js 6.06 kB
build/add-to-cart-form-rtl.css 444 B
build/add-to-cart-form.css 444 B
build/all-products-frontend.js 9.67 kB
build/all-products-rtl.css 4.54 kB
build/all-products.css 4.54 kB
build/all-products.js 39.7 kB
build/all-reviews-rtl.css 1.75 kB
build/all-reviews.css 1.75 kB
build/all-reviews.js 7.8 kB
build/attribute-filter-frontend.js 19.9 kB
build/attribute-filter-rtl.css 4.03 kB
build/attribute-filter-wrapper-frontend.js 21.1 kB
build/attribute-filter-wrapper-rtl.css 3.89 kB
build/attribute-filter-wrapper.css 3.88 kB
build/attribute-filter.css 4.01 kB
build/blocks-checkout.js 33.9 kB
build/blocks-components.js 31.8 kB
build/breadcrumbs-rtl.css 234 B
build/breadcrumbs.css 234 B
build/breadcrumbs.js 2.13 kB
build/cart-blocks/cart-accepted-payment-methods-frontend.js 1.4 kB
build/cart-blocks/cart-accepted-payment-methods-style.js 153 B
build/cart-blocks/cart-cross-sells-frontend.js 267 B
build/cart-blocks/cart-cross-sells-products-frontend.js 5.56 kB
build/cart-blocks/cart-cross-sells-products-style.js 153 B
build/cart-blocks/cart-cross-sells-style.js 269 B
build/cart-blocks/cart-express-payment-frontend.js 5.38 kB
build/cart-blocks/cart-express-payment-style.js 155 B
build/cart-blocks/cart-items-frontend.js 281 B
build/cart-blocks/cart-items-style.js 240 B
build/cart-blocks/cart-line-items-frontend.js 9.24 kB
build/cart-blocks/cart-line-items-style.js 153 B
build/cart-blocks/cart-order-summary-frontend.js 20.6 kB
build/cart-blocks/cart-order-summary-style.js 339 B
build/cart-blocks/cart-totals-frontend.js 296 B
build/cart-blocks/cart-totals-style.js 253 B
build/cart-blocks/empty-cart-frontend.js 376 B
build/cart-blocks/empty-cart-style.js 375 B
build/cart-blocks/filled-cart-frontend.js 614 B
build/cart-blocks/filled-cart-style.js 332 B
build/cart-blocks/order-summary-coupon-form-frontend.js 21 kB
build/cart-blocks/order-summary-coupon-form-style.js 155 B
build/cart-blocks/order-summary-discount-frontend.js 21 kB
build/cart-blocks/order-summary-discount-style.js 155 B
build/cart-blocks/order-summary-fee-frontend.js 288 B
build/cart-blocks/order-summary-fee-style.js 153 B
build/cart-blocks/order-summary-heading-frontend.js 347 B
build/cart-blocks/order-summary-heading-style.js 351 B
build/cart-blocks/order-summary-shipping-frontend.js 20.6 kB
build/cart-blocks/order-summary-shipping-style.js 154 B
build/cart-blocks/order-summary-subtotal-frontend.js 291 B
build/cart-blocks/order-summary-subtotal-style.js 154 B
build/cart-blocks/order-summary-taxes-frontend.js 456 B
build/cart-blocks/order-summary-taxes-style.js 202 B
build/cart-blocks/proceed-to-checkout-frontend.js 7.64 kB
build/cart-blocks/proceed-to-checkout-style.js 1.09 kB
build/cart-frontend.js 29 kB
build/cart-rtl.css 9.27 kB
build/cart.css 9.25 kB
build/catalog-sorting-rtl.css 259 B
build/catalog-sorting.css 259 B
build/catalog-sorting.js 1.7 kB
build/checkout-blocks/actions-frontend.js 8.15 kB
build/checkout-blocks/actions-style.js 1.02 kB
build/checkout-blocks/billing-address-frontend.js 9.86 kB
build/checkout-blocks/billing-address-style.js 574 B
build/checkout-blocks/contact-information-frontend.js 1.67 kB
build/checkout-blocks/contact-information-style.js 653 B
build/checkout-blocks/express-payment-frontend.js 5.82 kB
build/checkout-blocks/fields-frontend.js 375 B
build/checkout-blocks/fields-style.js 342 B
build/checkout-blocks/order-note-frontend.js 681 B
build/checkout-blocks/order-summary-cart-items-frontend.js 6.49 kB
build/checkout-blocks/order-summary-cart-items-style.js 153 B
build/checkout-blocks/order-summary-coupon-form-frontend.js 21 kB
build/checkout-blocks/order-summary-coupon-form-style.js 155 B
build/checkout-blocks/order-summary-discount-frontend.js 21.1 kB
build/checkout-blocks/order-summary-discount-style.js 154 B
build/checkout-blocks/order-summary-fee-frontend.js 291 B
build/checkout-blocks/order-summary-fee-style.js 155 B
build/checkout-blocks/order-summary-frontend.js 20.6 kB
build/checkout-blocks/order-summary-shipping-frontend.js 20.6 kB
build/checkout-blocks/order-summary-shipping-style.js 154 B
build/checkout-blocks/order-summary-style.js 341 B
build/checkout-blocks/order-summary-subtotal-frontend.js 289 B
build/checkout-blocks/order-summary-subtotal-style.js 155 B
build/checkout-blocks/order-summary-taxes-frontend.js 455 B
build/checkout-blocks/order-summary-taxes-style.js 201 B
build/checkout-blocks/payment-frontend.js 14.5 kB
build/checkout-blocks/payment-style.js 500 B
build/checkout-blocks/pickup-options-frontend.js 11.2 kB
build/checkout-blocks/pickup-options-style.js 481 B
build/checkout-blocks/shipping-address-frontend.js 9.8 kB
build/checkout-blocks/shipping-address-style.js 517 B
build/checkout-blocks/shipping-method-frontend.js 1.97 kB
build/checkout-blocks/shipping-method-style.js 1.44 kB
build/checkout-blocks/shipping-methods-frontend.js 19 kB
build/checkout-blocks/shipping-methods-style.js 456 B
build/checkout-blocks/terms-frontend.js 1.56 kB
build/checkout-blocks/terms-style.js 1.03 kB
build/checkout-blocks/totals-frontend.js 338 B
build/checkout-blocks/totals-style.js 301 B
build/checkout-frontend.js 30.6 kB
build/checkout-rtl.css 8.37 kB
build/checkout.css 8.35 kB
build/checkout.js 42.5 kB
build/classic-shortcode-rtl.css 242 B
build/classic-shortcode.css 241 B
build/classic-shortcode.js 4.66 kB
build/collection-filters.js 2.69 kB
build/collection-price-filter-frontend.js 591 B
build/collection-price-filter-rtl.css 1.07 kB
build/collection-price-filter.css 1.07 kB
build/collection-price-filter.js 2.15 kB
build/collection-stock-filter-frontend.js 396 B
build/collection-stock-filter-rtl.css 4.03 kB
build/collection-stock-filter.css 4.03 kB
build/collection-stock-filter.js 4.18 kB
build/customer-account-rtl.css 410 B
build/customer-account.css 409 B
build/customer-account.js 3.19 kB
build/featured-category-rtl.css 974 B
build/featured-category.css 973 B
build/featured-category.js 13.6 kB
build/featured-product-rtl.css 1.02 kB
build/featured-product.css 1.02 kB
build/featured-product.js 13.8 kB
build/filter-wrapper-frontend.js 14.6 kB
build/filter-wrapper-rtl.css 378 B
build/filter-wrapper.css 378 B
build/filter-wrapper.js 2.38 kB
build/handpicked-products.js 7.33 kB
build/legacy-template-rtl.css 240 B
build/legacy-template.css 240 B
build/legacy-template.js 7.85 kB
build/mini-cart-component-frontend.js 30.8 kB
build/mini-cart-contents-block/cart-button-frontend.js 1.86 kB
build/mini-cart-contents-block/cart-button-style.js 1.23 kB
build/mini-cart-contents-block/checkout-button-frontend.js 1.95 kB
build/mini-cart-contents-block/checkout-button-style.js 1.44 kB
build/mini-cart-contents-block/empty-cart-frontend.js 383 B
build/mini-cart-contents-block/empty-cart-style.js 387 B
build/mini-cart-contents-block/filled-cart-frontend.js 284 B
build/mini-cart-contents-block/filled-cart-style.js 287 B
build/mini-cart-contents-block/footer-frontend.js 3.87 kB
build/mini-cart-contents-block/footer-style.js 1.96 kB
build/mini-cart-contents-block/items-frontend.js 246 B
build/mini-cart-contents-block/items-style.js 250 B
build/mini-cart-contents-block/products-table-frontend.js 8.59 kB
build/mini-cart-contents-block/shopping-button-frontend.js 501 B
build/mini-cart-contents-block/shopping-button-style.js 361 B
build/mini-cart-contents-block/title-frontend.js 2.04 kB
build/mini-cart-contents-block/title-items-counter-frontend.js 1.74 kB
build/mini-cart-contents-block/title-items-counter-style.js 1.2 kB
build/mini-cart-contents-block/title-label-frontend.js 1.68 kB
build/mini-cart-contents-block/title-label-style.js 1.14 kB
build/mini-cart-contents-block/title-style.js 1.38 kB
build/mini-cart-contents-rtl.css 3.23 kB
build/mini-cart-contents.css 3.22 kB
build/mini-cart-contents.js 16 kB
build/mini-cart-frontend.js 2.35 kB
build/mini-cart-rtl.css 2.44 kB
build/mini-cart.css 2.44 kB
build/mini-cart.js 6.09 kB
build/order-confirmation-additional-information-rtl.css 367 B
build/order-confirmation-additional-information.css 367 B
build/order-confirmation-additional-information.js 1.58 kB
build/order-confirmation-billing-address-rtl.css 398 B
build/order-confirmation-billing-address.css 397 B
build/order-confirmation-billing-address.js 1.56 kB
build/order-confirmation-billing-wrapper.js 1.51 kB
build/order-confirmation-downloads-rtl.css 477 B
build/order-confirmation-downloads-wrapper.js 1.58 kB
build/order-confirmation-downloads.css 478 B
build/order-confirmation-downloads.js 1.91 kB
build/order-confirmation-shipping-address-rtl.css 399 B
build/order-confirmation-shipping-address.css 398 B
build/order-confirmation-shipping-address.js 1.56 kB
build/order-confirmation-shipping-wrapper.js 1.52 kB
build/order-confirmation-status-rtl.css 280 B
build/order-confirmation-status.css 280 B
build/order-confirmation-status.js 1.55 kB
build/order-confirmation-summary-rtl.css 460 B
build/order-confirmation-summary.css 460 B
build/order-confirmation-summary.js 1.76 kB
build/order-confirmation-totals-rtl.css 594 B
build/order-confirmation-totals-wrapper.js 1.8 kB
build/order-confirmation-totals.css 593 B
build/order-confirmation-totals.js 2.18 kB
build/packages-style-rtl.css 5.19 kB
build/packages-style.css 5.19 kB
build/page-content-wrapper.js 1.96 kB
build/price-filter-frontend.js 7.94 kB
build/price-filter-rtl.css 2.68 kB
build/price-filter-wrapper-frontend.js 8.11 kB
build/price-filter-wrapper-rtl.css 2.53 kB
build/price-filter-wrapper.css 2.53 kB
build/price-filter.css 2.67 kB
build/price-format.js 913 B
build/product-add-to-cart-frontend.js 8.12 kB
build/product-add-to-cart-rtl.css 1.37 kB
build/product-add-to-cart.css 1.38 kB
build/product-add-to-cart.js 8.36 kB
build/product-average-rating-frontend.js 1.88 kB
build/product-average-rating.js 1.4 kB
build/product-best-sellers.js 7.07 kB
build/product-button-frontend.js 4.94 kB
build/product-button-interactivity-frontend.js 8.47 kB
build/product-button-rtl.css 1.14 kB
build/product-button.css 1.14 kB
build/product-button.js 4.66 kB
build/product-categories-rtl.css 654 B
build/product-categories.css 654 B
build/product-categories.js 2.6 kB
build/product-category.js 8 kB
build/product-collection.js 13.9 kB
build/product-details-rtl.css 397 B
build/product-details.css 394 B
build/product-gallery-frontend.js 872 B
build/product-gallery-large-image-frontend.js 648 B
build/product-gallery-large-image.js 2.47 kB
build/product-gallery-rtl.css 1.26 kB
build/product-gallery.css 1.26 kB
build/product-image-frontend.js 2.89 kB
build/product-image-gallery-rtl.css 307 B
build/product-image-gallery.css 306 B
build/product-image-rtl.css 996 B
build/product-image.css 994 B
build/product-image.js 2.57 kB
build/product-new.js 7.33 kB
build/product-on-sale.js 7.32 kB
build/product-price-frontend.js 2.82 kB
build/product-price-rtl.css 644 B
build/product-price.css 643 B
build/product-price.js 2.34 kB
build/product-query-rtl.css 350 B
build/product-query.css 349 B
build/product-query.js 11.7 kB
build/product-rating-counter-frontend.js 2.19 kB
build/product-rating-counter.js 1.7 kB
build/product-rating-frontend.js 2.53 kB
build/product-rating-rtl.css 247 B
build/product-rating-stars-frontend.js 2.43 kB
build/product-rating-stars-rtl.css 899 B
build/product-rating-stars.css 900 B
build/product-rating-stars.js 1.95 kB
build/product-rating.css 246 B
build/product-rating.js 2.04 kB
build/product-results-count-rtl.css 230 B
build/product-results-count.css 230 B
build/product-results-count.js 1.66 kB
build/product-reviews-rtl.css 458 B
build/product-reviews.css 458 B
build/product-sale-badge-frontend.js 2.01 kB
build/product-sale-badge-rtl.css 437 B
build/product-sale-badge.css 437 B
build/product-sale-badge.js 1.52 kB
build/product-search-rtl.css 419 B
build/product-search.css 417 B
build/product-search.js 2.62 kB
build/product-sku-frontend.js 2.02 kB
build/product-sku-rtl.css 240 B
build/product-sku.css 239 B
build/product-sku.js 1.53 kB
build/product-stock-indicator-frontend.js 2.2 kB
build/product-stock-indicator-rtl.css 232 B
build/product-stock-indicator.css 232 B
build/product-stock-indicator.js 1.71 kB
build/product-summary-frontend.js 2.36 kB
build/product-summary-rtl.css 549 B
build/product-summary.css 549 B
build/product-summary.js 1.88 kB
build/product-tag.js 7.52 kB
build/product-template-rtl.css 536 B
build/product-template.css 535 B
build/product-template.js 2.81 kB
build/product-title-frontend.js 2.31 kB
build/product-title-rtl.css 693 B
build/product-title.css 694 B
build/product-title.js 2.05 kB
build/product-top-rated.js 7.6 kB
build/products-by-attribute.js 8.05 kB
build/rating-filter-frontend.js 18.8 kB
build/rating-filter-rtl.css 4.09 kB
build/rating-filter-wrapper-frontend.js 19.7 kB
build/rating-filter-wrapper-rtl.css 3.95 kB
build/rating-filter-wrapper.css 3.95 kB
build/rating-filter.css 4.08 kB
build/rating-filter.js 5.8 kB
build/reviews-by-category-rtl.css 1.75 kB
build/reviews-by-category.css 1.75 kB
build/reviews-by-category.js 11.4 kB
build/reviews-by-product-rtl.css 1.75 kB
build/reviews-by-product.css 1.75 kB
build/reviews-by-product.js 12.7 kB
build/reviews-frontend.js 6.44 kB
build/single-product-rtl.css 378 B
build/single-product.css 378 B
build/single-product.js 11.1 kB
build/stock-filter-frontend.js 19 kB
build/stock-filter-rtl.css 3.88 kB
build/stock-filter-wrapper-frontend.js 20 kB
build/stock-filter-wrapper-rtl.css 3.75 kB
build/stock-filter-wrapper.css 3.74 kB
build/stock-filter.css 3.87 kB
build/stock-filter.js 6.44 kB
build/store-notices.js 1.68 kB
build/wc-blocks-classic-template-revert-button-style-rtl.css 240 B
build/wc-blocks-classic-template-revert-button-style.css 239 B
build/wc-blocks-classic-template-revert-button.js 1.19 kB
build/wc-blocks-data.js 19.7 kB
build/wc-blocks-editor-style-rtl.css 7.06 kB
build/wc-blocks-editor-style.css 7.06 kB
build/wc-blocks-google-analytics.js 1.13 kB
build/wc-blocks-jetpack-woocommerce-analytics.js 750 B
build/wc-blocks-middleware.js 735 B
build/wc-blocks-registry.js 2.75 kB
build/wc-blocks-rtl.css 2.48 kB
build/wc-blocks-shared-context.js 860 B
build/wc-blocks-shared-hocs.js 1.41 kB
build/wc-blocks-vendors.js 61.7 kB
build/wc-blocks.css 2.48 kB
build/wc-interactivity-dropdown.js 453 B
build/wc-interactivity.js 10.7 kB
build/wc-payment-method-bacs.js 405 B
build/wc-payment-method-cheque.js 402 B
build/wc-payment-method-cod.js 508 B
build/wc-payment-method-paypal.js 439 B
build/wc-settings.js 2.42 kB
build/wc-shipping-method-pickup-location.js 29.4 kB

compressed-size-action

@thealexandrelara thealexandrelara changed the title WIP: experimenting with strategy pattern for block registration Product Gallery block: Restrict block to be available only on the Single Product template or the Product Gallery template part Nov 8, 2023
@thealexandrelara thealexandrelara self-assigned this Nov 10, 2023
@thealexandrelara thealexandrelara added type: enhancement The issue is a request for an enhancement. skip-changelog PRs that you don't want to appear in the changelog. block: product gallery Issues related to the Product Gallery block. labels Nov 13, 2023
@thealexandrelara thealexandrelara added this to the 11.6.0 milestone Nov 13, 2023
@thealexandrelara thealexandrelara marked this pull request as ready for review November 13, 2023 18:51
@woocommercebot woocommercebot requested review from a team and Aljullu and removed request for a team November 13, 2023 18:52
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 is testing great! Thanks @thealexandrelara for working on this, it's definitely a tricky topic.

I noticed that with this approach we need to define the blocks with registration restrictions in blocks-with-restriction.ts. Do you think it would be possible to create a util wrapping registerBlockType() which takes care of that? So we would only need to call that util (ie: registerBlockTypeWithRestrictions()) when registering the block instead of having to modify blocks-with-restriction.ts if we ever need to do this for other blocks.

By the way, it might be a good idea to add some e2e tests to make sure we don't introduce regressions on this feature in the future. What do you think?

@thealexandrelara
Copy link
Contributor Author

thealexandrelara commented Nov 14, 2023

I noticed that with this approach we need to define the blocks with registration restrictions in blocks-with-restriction.ts. Do you think it would be possible to create a util wrapping registerBlockType() which takes care of that? So we would only need to call that util (ie: registerBlockTypeWithRestrictions()) when registering the block instead of having to modify blocks-with-restriction.ts if we ever need to do this for other blocks.

Thank you for reviewing and suggesting this approach! Let me provide more context about why this approach is being used here.

Currently, we have the assets/js/atomic/utils/register-block-single-product-template.ts, which works as a wrapper for the registerBlockType() and registerBlockVariation() functions. One of the issues we encounter when using this wrapper is that, for each component that utilizes it, we subscribe to the data store (core/edit-site and core/edit-post). Consequently, every time the store is updated, this logic is triggered for each subscriber.

We currently have approximately 8 blocks using this approach. Since each instance of registerBlockSingleProductTemplate is isolated from the others, they are triggered independently, but they update the store simultaneously. This can lead to racing conditions (#9090).

The idea behind using this approach is to establish a single source of truth responsible for monitoring and responding to page/post or template changes, as well as registering/unregistering blocks based on the defined restrictions. This approach also prevents racing conditions since there is a single point responsible for block registration/unregistration. Another advantage is improved performance, as we only have one subscriber to the store, which triggers the logic for managing the blocks only when merchants go from one post/page to another or from one template to another.

Regarding your suggestion, what changes do you think we could make to retain these benefits while avoiding the use of a separate file for block restrictions?

By the way, it might be a good idea to add some e2e tests to make sure we don't introduce regressions on this feature in the future. What do you think?

Sure! I'll be adding some e2e tests for the Product Gallery block to make sure the block is only available inside the Single Product template and not on the posts/pages.

@roykho
Copy link
Contributor

roykho commented Nov 14, 2023

I also had similar concerns as Albert. Is there a way to add metadata to the Product Gallery block and when it gets registered through the wrapper, it will pick up on the restrictions instead of using that restriction file?

@Aljullu
Copy link
Contributor

Aljullu commented Nov 15, 2023

The idea behind using this approach is to establish a single source of truth responsible for monitoring and responding to page/post or template changes, as well as registering/unregistering blocks based on the defined restrictions. This approach also prevents racing conditions since there is a single point responsible for block registration/unregistration. Another advantage is improved performance, as we only have one subscriber to the store, which triggers the logic for managing the blocks only when merchants go from one post/page to another or from one template to another.

That makes a lot of sense, @thealexandrelara! Thanks for the detailed explanation.

I was thinking about something along these lines:

export const registerBlockTypeWithRestrictions = (
	blockMetadata,
	blockSettings,
	{
		allowedTemplates,
		allowedTemplateParts,
		availableInPostOrPageEditor,
		isVariationBlock,
	}
) => {
	BLOCKS_WITH_RESTRICTION[ blockMetadata.name ] = {
		blockMetadata,
		blockSettings,
		allowedTemplates,
		allowedTemplateParts,
		availableInPostOrPageEditor,
		isVariationBlock,
	};
	registerBlockType( blockMetadata, blockSettings );
};

Which then could be called like this:

registerBlockTypeWithRestrictions(
	productGalleryBlockMetadata,
	ProductGalleryBlockSettings,
	{
		allowedTemplates: {
			'single-product': true,
		},
		allowedTemplateParts: {
			'product-gallery': true,
		},
		availableInPostOrPageEditor: false,
		isVariationBlock: false,
	}
);

I didn't test it, and it would probably require some internal refactoring, as BLOCKS_WITH_RESTRICTION would be a dynamic constant. So there might be some blockers that I'm not aware of. In any case, I wanted to share it as I think it would make the API much easier to work with.

Besides that, everything looks good to me. 👌

@thealexandrelara
Copy link
Contributor Author

thealexandrelara commented Nov 15, 2023

Thank you for your suggestions, it would be awesome to have this API and it would make much easier to maintain. I was testing your suggestions for improving the API and creating a wrapper around the registerBlockType. However, it appears to be more complex than I initially expected. The issue is that the BlocksRegistrationManager only runs when there's a template or page change. When you first load the page, the function runs as soon as the page loads. However, the blocks are registered later. Since the block isn't registered before the manager runs, the manager doesn't know when it should remove the block, making it available in places where it shouldn't (when loading the page for the first time).

I'll be AFK for the next few weeks, but this PR will be essential for the Product Gallery block. I believe I can improve this API when we start migrating other blocks to use the BlocksRegistrationManager. The other option would be for someone else to continue working on this and improve the API before merging it. What do you think?

P.S.: I've just enabled auto-merge, so once this PR is approved it will be automatically merge.

@thealexandrelara thealexandrelara enabled auto-merge (squash) November 15, 2023 23:58
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.

Makes sense, thanks @thealexandrelara! Given that it's not a public API, I think it's fine to iterate on it after merge. I left some last comments here and there, but everything else LGTM.

I will go ahead and push some fixes directly to this PR, as I think at least the JS error is a blocking one.

@Aljullu
Copy link
Contributor

Aljullu commented Nov 16, 2023

@roykho I pushed some additional commits to this PR. Would you mind taking a second look to make sure I didn't mess anything up? 🙏

@roykho
Copy link
Contributor

roykho commented Nov 16, 2023

@Aljullu - it's working correctly thanks for the additions.

Copy link
Contributor

@roykho roykho left a comment

Choose a reason for hiding this comment

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

Thanks for working on this. Everything is testing as described even the e2e tests. Great job!

…o-single-product-page-or-product-gallery-template-part
@thealexandrelara thealexandrelara merged commit 83e5b64 into trunk Nov 16, 2023
@thealexandrelara thealexandrelara deleted the feat/11027-restrict-product-gallery-block-to-single-product-page-or-product-gallery-template-part branch November 16, 2023 15:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
block: product gallery Issues related to the Product Gallery block. skip-changelog PRs that you don't want to appear in the changelog. type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Product Gallery: the block should be addable only in the Single Product Template and in the Product Gallery template-part
3 participants