New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Product Collection: Parse front-end context #44145
base: trunk
Are you sure you want to change the base?
Conversation
Test Results SummaryCommit SHA: a48b3ec
To view the full API test report, click here. To view the full E2E test report, click here. To view all test reports, visit the WooCommerce Test Reports Dashboard. |
Hi @kmanijak, Apart from reviewing the code changes, please make sure to review the testing instructions as well. You can follow this guide to find out what good testing instructions should look like: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @chli,
I've reviewed the code of this PR, and it looks good to me so far. However, I'm uncertain about conducting thorough testing since the PR hasn't covered all cases yet. Should I wait for my review until it fully addresses all cases? 🙂
…context to collection children
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @xristos3490, great work! 🙌
I believe we're almost at the finish line. I've left a couple of minor suggestions for you to consider.
plugins/woocommerce/src/Blocks/BlockTypes/ProductCollection.php
Outdated
Show resolved
Hide resolved
plugins/woocommerce/src/Blocks/BlockTypes/ProductCollection.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @xristos3490,
I've dropped a few minor comments. I plan to do a bit more testing later today but wanted to share this feedback with you now. Also, it would be wonderful if @kmanijak could also give it a quick review.
Thanks for the amazing work 🙌🏻
plugins/woocommerce/src/Blocks/BlockTypes/ProductCollection.php
Outdated
Show resolved
Hide resolved
plugins/woocommerce/src/Blocks/Utils/ProductCollectionUtils.php
Outdated
Show resolved
Hide resolved
if ( 'woocommerce/product-collection' === $block['blockName'] | ||
&& isset( $block['attrs']['query']['isProductCollectionBlock'] ) ) { | ||
$this->product_collection_inner_blocks_names = array_reverse( | ||
$this->extract_inner_block_names( $block ) | ||
); | ||
} | ||
|
||
$this->provide_location_context_inner_blocks( $block, $context ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I found this logic a bit hard to understand. Here is what I understood, please correct me if I am wrong.
-
Then, our logic depends on the fact that
render_block_context
will be executed in following sequence on Frontend:
-
Based on above fact, we push the items on Stack (
product_collection_inner_blocks_names
) & then start popping those items. -
Question: Is it good idea to assume that flow of
render_block_context
hook will always be like this in future? Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CC: @thealexandrelara As you worked on implementing similar logic in woocommerce/woocommerce-blocks#8610
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand that the current method of working with inner blocks may not be ideal, but it appeared to be functioning with the Single Product block. It's essential to consider that the inner blocks structure in a Product Collection can be anything and that other blocks, such as the no-results block, will also require access to that context, as you mentioned.
Upon reading this comment, it sparked some thoughts that led me to realize that there may be a problem with how the system operates. This issue impacts both the current case and the Single Product block. Upon further investigation, my assumptions proved to be accurate. I have provided a detailed explanation of this problem here:
I will work on developing a better plan to handle edge cases, and hopefully, I can also resolve the issue in the single product container.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon further testing, it seems the issue here is more severe than I anticipated. This is because every time the woocommerce/product-template
block is rendered, it runs through every inner block for each individual product in the query results. As a result, the required execution sequence is being destroyed.
Back to the drawing board.
Update: The existence of a product-template
block (either within a Query Loop or a Product Collection block) breaks the Single Product block as well for the same reason - #45342 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm glad that it sparked some thoughts and that you were able to identify the edge cases where this approach does not work as expected. It would be great if you could find a simpler and more effective solution to this 🙂
Does this mean that we cannot merge this PR until we have found a better solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, regarding #44145 (comment):
How do you feel about using Reflection to access available_context
property? Something like this:
$reflector = new ReflectionObject( $parent_block );
$property = $reflector->getProperty( 'available_context' );
$property->setAccessible( true );
$available_context = $property->getValue( $parent_block );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CC: @thealexandrelara As you worked on implementing similar logic in woocommerce/woocommerce-blocks#8610
It's been a while since I last looked at that code 😅 . TBH, when the Single Product block was created, we didn't anticipate the possibility of it being nested within another Single Product block. I believe that if that's a valid use case, we could probably change the logic to support it. Each rendered block has a unique clientId
, so perhaps we can use that identifier to differentiate between different block instances and apply the corresponding context for each nested block (I'm not sure if that is actually possible, so I'm just braintorming here).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, It would be better to use isProductCollectionBlock instead. You may find some examples by searching isProductCollectionBlock in this file
@imanish003, It seems to me that using the query
context is the best choice for this situation. If that's what you meant, then you're absolutely right!
After taking a closer look into how the block context works in PHP, it seems that utilizing WordPress's native context is the most efficient and straightforward approach to bypass the barrier of the protected $available_context
.
This guarantees that the location context is only added within the context of blocks that use the "query" context and include the [query][isProductCollectionBlock]
value, which helps identify the inner blocks.
I made these changes here: 17de651, and they seem to be working great! Can you take another look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for chiming in, @thealexandrelara!
we didn't anticipate the possibility of it being nested within another Single Product block
💯 agree that this is an edge case!
For me, the main issue that this PR surfaced is the one I described in #45374. The product-template
spawns new blocks during render, which are not accounted for in the block names execution stack, causing a break in the flow when adding the single product's context.
plugins/woocommerce/src/Blocks/BlockTypes/ProductCollection.php
Outdated
Show resolved
Hide resolved
plugins/woocommerce/src/Blocks/BlockTypes/ProductCollection.php
Outdated
Show resolved
Hide resolved
Co-authored-by: Manish Menaria <the.manish.menaria@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @xristos3490 !
Testing:
- in post
- in Single Product block in post
- in page
- in Single Product block in page
- in Category
- in Single Product block in Category
- in specific Singe Product
- in Single Product block in specific Single Product
- ❌ in Cart - lack of
productIds
and PHP error - details below - in Single Product block in Cart
- in Products by Category
- in Single Product block in Products by Category
- in Products by Tag
- in Single Product block in Products by Tag
- in Products by Attribute
- in Single Product block in Products by Attribute
- in Order Confirmation
- in Single Product block in Order Confirmation
- ❌ in Cart - there's no
productIds
even though there are products in Cart
There's also PHP error:
Submission Review Guidelines:
Changes proposed in this Pull Request:
This Pull Request parses the front-end location context for each Product Collection block and passes it to its context.
Context Levels
The context is parsed per block. This happens because it's easier to serve the following priorities:
wp_query
.Requirements
Possible contexts:
All need to be specific and fill in the required source data:
Note
By default, context is only retrieved in pages and entities related to WooCommerce. This means that if a post contains a product collection block or a non-related taxonomy like
category
, the context will be empty and default to site.Closes #44144
How to test the changes in this Pull Request:
Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:
Before testing
Testing
Negative testing
category
tax archive returns the generic context.Changelog entry
Significance
Type
Message
Comment