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

Conversation

gigitux
Copy link
Contributor

@gigitux gigitux commented Feb 1, 2023

This is an attempt to fix #8314. This PR is an exploration that I did, and I would like to receive feedback to see if it makes sense to wrap up my work.

Fixes #8314

Screenshots

Testing

Automated Tests

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

User Facing Testing

Check out this branch.

  1. Edit the Single Product Template.
  2. Be sure that a group block wraps the Single Product Template.
  3. On the frontend page, be sure that the Single Product Template is wrapped with a div with the classes woocommerce and product.
  4. Merge Add Product Image Gallery  #8235 in this branch.
  5. Follow the testing instructions of Add Product Image Gallery  #8235.
  6. You can notice that the style of the Product Image Gallery is loaded correctly.
  • Do not include in the Testing Notes

WooCommerce Visibility

  • WooCommerce Core
  • Feature plugin
  • Experimental

Performance Impact

@github-actions
Copy link
Contributor

github-actions bot commented Feb 1, 2023

The release ZIP for this PR is accessible via:

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

Script Dependencies Report

There is no changed script dependency between this branch and trunk.

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

TypeScript Errors Report

  • Files with errors: 496
  • Total errors: 2341

🎉 🎉 This PR does not introduce new TS errors.

comments-aggregator

@github-actions
Copy link
Contributor

github-actions bot commented Feb 1, 2023

Size Change: 0 B

Total Size: 1.1 MB

ℹ️ View Unchanged
Filename Size
build/active-filters-frontend.js 7.98 kB
build/active-filters-wrapper-frontend.js 6 kB
build/active-filters.js 7.33 kB
build/all-products-frontend.js 11.7 kB
build/all-products.js 34.2 kB
build/all-reviews.js 7.67 kB
build/attribute-filter-frontend.js 22.9 kB
build/attribute-filter-wrapper-frontend.js 7.67 kB
build/attribute-filter.js 12.3 kB
build/blocks-checkout.js 41.2 kB
build/breadcrumbs.js 2.05 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.69 kB
build/cart-blocks/cart-express-payment--checkout-blocks/express-payment-frontend.js 5.17 kB
build/cart-blocks/cart-express-payment-frontend.js 720 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.36 kB
build/cart-blocks/cart-line-items-frontend.js 1.07 kB
build/cart-blocks/cart-order-summary-frontend.js 1.24 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 654 B
build/cart-blocks/order-summary-coupon-form-frontend.js 1.62 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 455 B
build/cart-blocks/order-summary-shipping-frontend.js 14.8 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.7 kB
build/cart.js 47.2 kB
build/catalog-sorting.js 1.7 kB
build/checkout-blocks/actions-frontend.js 1.85 kB
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 3.92 kB
build/checkout-blocks/billing-address-frontend.js 1.18 kB
build/checkout-blocks/contact-information-frontend.js 2.05 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.78 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.24 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.43 kB
build/checkout-blocks/pickup-options-frontend.js 2.8 kB
build/checkout-blocks/shipping-address-frontend.js 1.14 kB
build/checkout-blocks/shipping-method-frontend.js 2.27 kB
build/checkout-blocks/shipping-methods-frontend.js 4.78 kB
build/checkout-blocks/terms-frontend.js 1.56 kB
build/checkout-blocks/totals-frontend.js 324 B
build/checkout-frontend.js 30.3 kB
build/checkout.js 43.7 kB
build/customer-account.js 3.12 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.85 kB
build/mini-cart-component-frontend.js 27.9 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.79 kB
build/mini-cart-contents-block/items-frontend.js 237 B
build/mini-cart-contents-block/products-table-frontend.js 591 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 17 kB
build/mini-cart-frontend.js 2 kB
build/mini-cart.js 4.3 kB
build/price-filter-frontend.js 13.9 kB
build/price-filter-wrapper-frontend.js 6.99 kB
build/price-filter.js 8.39 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 253 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.73 kB
build/product-add-to-cart.js 8.63 kB
build/product-best-sellers.js 7.6 kB
build/product-button--product-category-list--product-image--product-price--product-rating--product-sale-b--e17c7c01.js 496 B
build/product-button--product-image--product-price--product-rating--product-sale-badge--product-title.js 258 B
build/product-button-frontend.js 2.19 kB
build/product-button.js 3.99 kB
build/product-categories.js 2.36 kB
build/product-category-list-frontend.js 1.19 kB
build/product-category-list.js 503 B
build/product-category.js 8.58 kB
build/product-image-frontend.js 2.2 kB
build/product-image.js 4.09 kB
build/product-new.js 7.58 kB
build/product-on-sale.js 7.91 kB
build/product-price-frontend.js 2.29 kB
build/product-price.js 1.58 kB
build/product-query.js 6.08 kB
build/product-rating-frontend.js 1.62 kB
build/product-rating.js 919 B
build/product-results-count.js 1.65 kB
build/product-sale-badge-frontend.js 1.43 kB
build/product-sale-badge.js 816 B
build/product-search.js 2.63 kB
build/product-sku-frontend.js 629 B
build/product-sku.js 378 B
build/product-stock-indicator-frontend.js 1.32 kB
build/product-stock-indicator.js 646 B
build/product-summary-frontend.js 1.58 kB
build/product-summary.js 920 B
build/product-tag-list-frontend.js 1.18 kB
build/product-tag-list.js 498 B
build/product-tag.js 8.07 kB
build/product-title-frontend.js 1.62 kB
build/product-title.js 3.46 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.19 kB
build/rating-filter.js 7.4 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.8 kB
build/single-product.js 9.98 kB
build/stock-filter-frontend.js 21.1 kB
build/stock-filter-wrapper-frontend.js 5.85 kB
build/stock-filter.js 8.13 kB
build/store-notices.js 1.65 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.4 kB
build/wc-blocks-editor-style-rtl.css 5.54 kB
build/wc-blocks-editor-style.css 5.54 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 933 B
build/wc-blocks-registry.js 3.15 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 26.5 kB
build/wc-blocks-style.css 26.5 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.4 kB
build/wc-blocks.js 2.65 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
build/wp-directives-runtime.js 2.4 kB
build/wp-directives-vendors.js 7.89 kB

compressed-size-action

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 solution looks promising. Good job, @gigitux!

As I said above, I didn't check all the cases. For example, my PR doesn't work if a group block doesn't wrap up the Single Product Template. For this reason, it is necessary to increase the unit test coverage and catch all the edge cases.

To solve this, I wonder if instead of wrapping the first block which is not inside a template part, maybe we should:

  • Wrap all blocks starting from the first one which is not inside a template part and finishing at the last block before the next template part (aka footer) or the last block in the page in case there is no footer. In other words, wrapping all blocks between the header and the footer instead of only wrapping the first one. That would solve the issue you described, no?
  • I would also add a check that inside the blocks we are wrapping, there is the Add to Cart form block or another block we know is required in the Single Product page. That would solve the issue of adding the wrapper when not needed (ie, when using the WooCommerce Classic Template).

Do you think that would work?

Comment on lines +413 to +417
'<!-- wp:group {"className":"woocommerce product"} -->
<div class="wp-block-group woocommerce product">
%1$s
</div>
<!-- /wp:group -->',
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't have a strong opinion, but I'm curious to know why you defined a Group block instead of simply a div?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm using parse_blocks function to generate the new structure. In the WordPress template markup, the div is represented with a block group. This is the reason I decided to define a Group block.

@gigitux
Copy link
Contributor Author

gigitux commented Feb 2, 2023

Thanks for the review!

  • Wrap all blocks starting from the first one which is not inside a template part and finishing at the last block before the next template part (aka footer) or the last block in the page in case there is no footer. In other words, wrapping all blocks between the header and the footer instead of only wrapping the first one. That would solve the issue you described, no?

Yeah, good point! I updated the code :)

I would also add a check that inside the blocks we are wrapping, there is the Add to Cart form block or another block we know is required in the Single Product page. That would solve the issue of adding the wrapper when not needed (ie, when using the WooCommerce Classic Template).

👍

@gigitux
Copy link
Contributor Author

gigitux commented Feb 3, 2023

Hey @Aljullu, the PR is ready to review.
I improved the logic and increased the coverage of unit test.

@gigitux gigitux self-assigned this Feb 3, 2023
@gigitux gigitux requested a review from Aljullu February 3, 2023 11:37
@gigitux gigitux marked this pull request as ready for review February 3, 2023 11:37
@woocommercebot woocommercebot requested a review from a team February 3, 2023 11:38
@gigitux gigitux added skip-changelog PRs that you don't want to appear in the changelog. type: compatibility labels Feb 3, 2023
…e-investigate-how-to-apply-wc-core-styles-to-product-template
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 more robust, but there is still the (edge) case that if somebody adds a block above the Header, this will break:

Editor Frontend
imatge imatge

(Notice how the paragraph This is a product and the Breadcrumb block are below the Header in the editor but above it in the frontend)


This is not a straight-forward issue because there are many possible edge cases. What I would try to do:

  • Step 1: Split all blocks/template parts. Grouping blocks that don't have template parts in between.
  • Step 2: Go through each block/group of blocks and run has_single_product_template_blocks(). If true, then run create_wrap_block_group().

Example

Imagine we have a page with a block above the header and a block below the footer:

  • B1 + TP1 + B2 + B3 + B4 + TP2 + B5
    (B = Block, TP = Template Part)

Step 1: You would split the blocks/template parts and store them in an array, using TP as delimiters:

  • [[B1], [TP1], [B2, B3, B4], [TP2], [B5]]

Step 2: for each item of this array, you would just need to run has_single_product_template_blocks() and create_wrap_block_group() as needed.

If B2, B3 or B4 were a "product template block", you would end up with a wrapper between B2 and B4.

There might be other solutions, but this was the first one that came to my mind. I might have missed some other edge case as well.

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

gigitux commented Feb 3, 2023

This looks more robust, but there is still the (edge) case that if somebody adds a block above the Header, this will break:

Good point. The assumption that I made is wrong. 👍

This is not a straight-forward issue because there are many possible edge cases. What I would try to do:
Step 1: Split all blocks/template parts. Grouping blocks that don't have template parts in between.
Step 2: Go through each block/group of blocks and run has_single_product_template_blocks(). If true, then run create_wrap_block_group().

Having multiple div with the same class could break some extensions, no? 🤔

@Aljullu
Copy link
Contributor

Aljullu commented Feb 3, 2023

Having multiple div with the same class could break some extensions, no? 🤔

Hmmm, maybe, but some extensions could break as well if some "product template blocks" (ie: Product Gallery and Add to Cart) are not wrapped in <div class="product">, no? I would expect having multiple <div class="product"> to be less problematic, but I might be wrong.

@gigitux
Copy link
Contributor Author

gigitux commented Feb 3, 2023

Having multiple div with the same class could break some extensions, no? 🤔

Hmmm, maybe, but some extensions could break as well if some "product template blocks" (ie: Product Gallery and Add to Cart) are not wrapped in <div class="product">, no? I would expect having multiple <div class="product"> to be less problematic, but I might be wrong.

Yeah, I guess that this is the only way to go. I updated the PR and added another test.

@github-actions
Copy link
Contributor

This PR has been marked as stale because it has not seen any activity within the past 7 days. Our team uses this tool to help surface pull requests that have slipped through review.

If deemed still relevant, the pr can be kept active by ensuring it's up to date with the main branch and removing the stale label.

@github-actions github-actions bot added the status: stale Stale issues and PRs have had no updates for 60 days. label Feb 11, 2023
@Aljullu Aljullu removed the status: stale Stale issues and PRs have had no updates for 60 days. label Feb 11, 2023
@gigitux gigitux requested a review from Aljullu February 13, 2023 09:28
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.

I left some other questions and comments regarding to the code. But once they are fixed/answered, it should be ready to go! Awesome work, @gigitux!

}
$wrapped_blocks = array_map(
function( $blocks ) use ( $single_product_template_blocks ) {
$has_single_product_template_blocks = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this line be removed? In L385 we are setting $has_single_product_template_blocks again.

Comment on lines 482 to 486
$last_element_index = count( $carry ) - 1;
if ( isset( $carry[ $last_element_index ][0]['blockName'] ) && 'core/template-part' !== $carry[ $last_element_index ][0]['blockName'] ) {
array_push( $carry[ $last_element_index ], $block );
return $carry;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess you can use the end() PHP function here to simplify the code:

$last_element = end( $carry );
if ( isset( $last_element[0]['blockName'] ) && 'core/template-part' !== $last_element[0]['blockName'] ) {
	array_push( $last_element, $block );
	return $carry;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mmm, I tried with your suggestion but the test failed. I suspect it happens because we don't push the updated element in the carry.

So, I prefer to not change anything here. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

It sounds good, I might have missed something. If you keep it as-is, I think you'll need to add an extra check in the case that count( $carry ) is 0, because then the code will try to use $carry[ -1 ] and produce a warning.

$parsed_blocks = parse_blocks( $template_content );
$grouped_blocks = self::group_blocks( $parsed_blocks );

$single_product_template_blocks = array( 'woocommerce/breadcrumbs', 'woocommerce/product-gallery-image', 'woocommerce/product-add-to-cart', 'woocommerce/product-details', 'woocommerce/add-to-cart-form' );
Copy link
Contributor

Choose a reason for hiding this comment

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

When using the classic template, the breadcrumbs are shown outside of the .product div, so I think we should exclude breadcrumbs from this list.

imatge

Also woocommerce/product-add-to-cart is used in the Products block, but not in the Single Product template, no? Should we remove it from the list as well? 🤔

@github-actions github-actions bot added this to the 9.6.0 milestone Feb 13, 2023
@gigitux gigitux modified the milestones: 9.6.0, 9.7.0 Feb 13, 2023
…ocks into fix/8314-blockifying-single-product-template-investigate-how-to-apply-wc-core-styles-to-product-template
…ocks into fix/8314-blockifying-single-product-template-investigate-how-to-apply-wc-core-styles-to-product-template
@gigitux gigitux force-pushed the fix/8314-blockifying-single-product-template-investigate-how-to-apply-wc-core-styles-to-product-template branch from f2bc9e7 to c8cd88e Compare February 14, 2023 12:29
@gigitux
Copy link
Contributor Author

gigitux commented Feb 14, 2023

Via 57cea7c, I added another check to be sure that we wrap the template only on the frontend side. I will wait for your feedback before merging this PR! @Aljullu

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.

Good catch. It makes sense to me.

@gigitux gigitux merged commit 9e98c27 into trunk Feb 15, 2023
@gigitux gigitux deleted the fix/8314-blockifying-single-product-template-investigate-how-to-apply-wc-core-styles-to-product-template branch February 15, 2023 09:27
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
skip-changelog PRs that you don't want to appear in the changelog. type: compatibility
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Blockifying Single Product Template]: Investigate how to apply WC Core styles to product template
2 participants