Skip to content
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 Block Editor: Add the fundamental setup for the custom product blocks and map Select and BooleanSelect inputs to the custom select field block #2164

Conversation

eason9487
Copy link
Member

@eason9487 eason9487 commented Nov 28, 2023

Changes proposed in this Pull Request:

To be compatible with Product Block Editor, this PR adds fundamental support:

  • Adjust the can_enqueue of BaseAsset as it should allow $enqueue_condition_callback to be null.
  • Adjust the AttributesBlock to register the custom blocks and the related assets.
  • Adjust the frontend config to build the custom blocks.
  • Add the structure of custom blocks.
  • Update the @woocommerce/dependency-extraction-webpack-plugin package to get the support of the newer WC packages.

To show how to develop and use the custom product blocks, this PR:

  • Implement the custom block of the product select field.
  • Map Select and BooleanSelect inputs to the custom block of the select field.

Screenshots:

📷 Simple product

image

📷 Variable product

image

📷 Variation product

image

Detailed test instructions:

📌 Prepare test environment

  1. Please refer to the test preparation in PR 2151.
  2. npm install
  3. npm start

📌 Test the simple product type

  1. Go to edit a simple product, e.g. the Beanie with Logo imported from WC's sample products
  2. Switch to the Organization tab and find the Google Listings & Ads section.
  3. Operate the selection fields and change their selected option.
  4. Click on the Update button at the top-right of the page.
  5. Refresh the page or switch back to the classical product editor to see if the changed options are saved.

📌 Test the variable and variation product type

  1. Go to edit a variable product, e.g. the Hoodie imported from WC's sample products
  2. Switch to the Organization tab and find the Google Listings & Ads section.
  3. Within the Google Listings & Ads section, there should be two fields. Operate the selection field and change its selected option.
  4. Click on the Update button at the top-right of the page.
  5. Refresh the page or switch back to the classical product editor to see if the changed option is saved.
  6. Back to edit the same variable product with Product Block Editor.
  7. Switch to the Variations tab and find the Variations section.
  8. Click on one of the Edit links within the Variations section to go to edit a variation product.
  9. With the General tab, find the Google Listings & Ads section.
  10. Repeat the similar test to verify the fields for this variation product.

📌 Test the related filters

  1. Go to edit a simple product.
  2. Filters the options for each attribute - "woocommerce_gla_product_attribute_value_options_{$attribute_id}"
    1. Confirm the Condition field has four options: Default, New, Refurbished, and Used.
    2. Add a filter to the google-listings-and-ads.php file:
      add_filter(
      	'woocommerce_gla_product_attribute_value_options_condition',
      	function ( array $value_options ) {
      		$value_options[ 'broken' ] = 'Broken';
      		return $value_options;
      	}
      );
    3. Refresh the page.
    4. Check if the Condition has the fifth option: Broken.
      image

Additional details:

With WooCommerce 8.3.0, the tooltip is not aligned well, and the generic product blocks don't support the tooltip attribute.

image

These issues will be resolved in WooCommerce 8.4.0, so this PR won't take care of them.

image

Changelog entry

@github-actions github-actions bot added changelog: add A new feature, function, or functionality was added. type: enhancement The issue is a request for an enhancement. labels Nov 28, 2023
@eason9487 eason9487 force-pushed the add/product-block-editor-custom-block-infra branch from ad893dd to ca54755 Compare November 28, 2023 12:15
@eason9487 eason9487 self-assigned this Nov 28, 2023
Copy link

codecov bot commented Nov 28, 2023

Codecov Report

Attention: 4 lines in your changes are missing coverage. Please review.

Comparison is base (9ff6a97) 60.6% compared to head (5e1f98d) 60.8%.
Report is 1 commits behind head on feature/support-product-block-editor.

Additional details and impacted files

Impacted file tree graph

@@                           Coverage Diff                            @@
##             feature/support-product-block-editor   #2164     +/-   ##
========================================================================
+ Coverage                                    60.6%   60.8%   +0.2%     
- Complexity                                   4144    4151      +7     
========================================================================
  Files                                         453     453             
  Lines                                       17785   17824     +39     
========================================================================
+ Hits                                        10777   10843     +66     
+ Misses                                       7008    6981     -27     
Flag Coverage Δ
php-unit-tests 60.8% <90.7%> (+0.2%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
src/Admin/Input/Select.php 100.0% <100.0%> (ø)
src/Assets/BaseAsset.php 54.9% <100.0%> (+5.7%) ⬆️
...ernal/DependencyManagement/CoreServiceProvider.php 0.0% <0.0%> (ø)
src/Admin/Product/Attributes/AttributesBlock.php 94.8% <90.0%> (-2.3%) ⬇️

... and 4 files with indirect coverage changes

@eason9487 eason9487 changed the title Product Block Editor: Add the fundamental setup for the custom product blocks and map Select and BooleanSelect inputs to the custom block of the select field Product Block Editor: Add the fundamental setup for the custom product blocks and map Select and BooleanSelect inputs to the custom select field block Nov 28, 2023
@eason9487 eason9487 force-pushed the add/product-block-editor-custom-block-infra branch 3 times, most recently from 917931b to 220dd41 Compare November 29, 2023 10:57
@eason9487 eason9487 marked this pull request as ready for review November 29, 2023 11:17
@eason9487 eason9487 requested a review from a team November 29, 2023 11:17
@eason9487 eason9487 force-pushed the add/product-block-editor-custom-block-infra branch from 220dd41 to 6f17074 Compare November 30, 2023 02:18
@eason9487 eason9487 force-pushed the add/product-block-editor-generic-blocks branch from 9a81d84 to 0408038 Compare December 7, 2023 04:50
@eason9487 eason9487 force-pushed the add/product-block-editor-custom-block-infra branch from 6f17074 to a308eb7 Compare December 7, 2023 04:50
Copy link
Contributor

@puntope puntope left a comment

Choose a reason for hiding this comment

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

✅ LGTM. Thanks for working on this.

  • I tested changing values in Products Single, Variable and Variations. They worked and they persisted after refreshing.
  • I tested adding custom values in the fields and also updating the values after.

In regards the code I didn't see any blocker. I left some 💅 and some questions. But as they are not blockers I approve this in advance.

Comment on lines +15 to +20
├── product-select-field/ # A custom block
│ ├── block.json # The metadata file of this block and also the canonical way to register this block with both PHP and JavaScript side
│ └── edit.js # The component to work with the `edit` function when registering this block, and it's the interface for how this block is going to be rendered within the Product Block Editor
├── another-field/ # Another custom block
│ ├── block.json
│ └── edit.js
Copy link
Contributor

Choose a reason for hiding this comment

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

💅 Thanks for documenting the structure. I'd suggest adding the Custom Blocks in their folder (ie custom_blocks, fields... ) so they are not at the same level as the components folder.

Copy link
Member Author

Choose a reason for hiding this comment

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

Since at most there will only be 3 or 4 custom blocks, I lead toward not using a deeper directory structure.

@@ -130,6 +130,10 @@ public function get_uri(): string {
* @return bool
*/
public function can_enqueue(): bool {
if ( is_null( $this->enqueue_condition_callback ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

💅 Can we cover this by test unit as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added in e4a743e.

@@ -0,0 +1 @@
{}
Copy link
Contributor

Choose a reason for hiding this comment

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

❓ Why is this file for?

Copy link
Member Author

@eason9487 eason9487 Dec 15, 2023

Choose a reason for hiding this comment

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

For testing the registration of custom blocks without actually building client files.

public function test_register_custom_blocks() {
$custom_blocks = [ 'existing-block', 'non-existent-block' ];
$expected_asset = new AdminScriptWithBuiltDependenciesAsset(
'google-listings-and-ads-product-blocks',
'tests/data/blocks',
GLA_TESTS_DATA_DIR . '/blocks.asset.php',
new BuiltScriptDependencyArray(
[
'dependencies' => [],
'version' => (string) filemtime( GLA_TESTS_DATA_DIR . '/blocks.js' ),
]
)
);
$this->assets_handler
->expects( $this->exactly( 1 ) )
->method( 'register' )
->with( $expected_asset );
$this->assets_handler
->expects( $this->exactly( 1 ) )
->method( 'enqueue' )
->with( $expected_asset );
$this->attributes_block->register_custom_blocks( GLA_TESTS_DATA_DIR, 'tests/data/blocks', $custom_blocks );
}

@@ -0,0 +1,35 @@
// Copied from WooCommerce core and simplified to leave only the needed parts.
Copy link
Contributor

Choose a reason for hiding this comment

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

💅 I assume it will be done in future PRs. I expected to have some tests for the JS part as well

Copy link
Member Author

Choose a reason for hiding this comment

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

Only using jest to test this component or custom blocks would be fragile as they involve a lot of Woo core mechanisms and codes. I planned to test them via E2E tests after all required development settled down.

Comment on lines +8 to +10
"_templateBlockHideConditions": {
"type": "array"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

❓ Why is this for? When I delete it I don't see any difference at first look

Copy link
Member Author

Choose a reason for hiding this comment

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

__experimentalRole is an undocumented attribute property, and is commonly set in WooCommerce core, but it seems a bit paradoxical. Although I did find the use of its source code, it's not clear what it's used for, only knew that: without this property, it may lead to a custom block in editing-disabled mode.

As the product block editor in Woo core is still under development, this issue may be/has been resolved. However, it would be safer to keep it for the time being.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the explanation. I was referring to

"_templateBlockHideConditions": {
			"type": "array"
		},

Copy link
Member Author

@eason9487 eason9487 Dec 25, 2023

Choose a reason for hiding this comment

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

Sorry, I got it wrong.

In order to make a custom block compatible with the conditionally hiding feature, it requires the _templateBlockHideConditions attribute when registering the custom block on both PHP and JS sides.

On JS side, a custom block can use registerProductEditorBlockType to inject that attribute, but on PHP side, there is no corresponding way to do so. Therefore, a custom block still needs to do a similar injection as BlockRegistry::register_block when calling Gutenberg register_block_type.

The good news is Woo 8.5.0 will have the core support by PR 41973 - Template API: Registration of custom block types, so the _templateBlockHideConditions attribute will be removed in a subsequent PR.

"tooltip": {
"type": "string"
},
"property": {
Copy link
Contributor

Choose a reason for hiding this comment

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

❓ Same for these "property" and "context". I don't see clear references out there but seems to be an essential part of the config.

Copy link
Member Author

Choose a reason for hiding this comment

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

The property value will be passed into the corresponding block and be used with the below useProductEntityProp to access a property or meta of product data. The naming is to align with all generic product blocks in Woo core, e.g. number, checkbox, radio and so on.

const [ value, setValue ] = useProductEntityProp( attributes.property, {
postType: context.postType,
} );

Not sure if the "context" refers to useContext. If yes, I added its use by this commit in PR #2178

Base automatically changed from add/product-block-editor-generic-blocks to feature/support-product-block-editor December 25, 2023 10:55
@eason9487 eason9487 merged commit cb432d9 into feature/support-product-block-editor Dec 25, 2023
15 checks passed
@eason9487 eason9487 deleted the add/product-block-editor-custom-block-infra branch December 25, 2023 10:58
@eason9487 eason9487 mentioned this pull request Feb 27, 2024
21 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: add A new feature, function, or functionality was added. type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants