8000 Add taxonomy block using SelectTree by nathanss · Pull Request #39947 · woocommerce/woocommerce · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add taxonomy block using SelectTree #39947

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

Merged
merged 15 commits into from
Aug 31, 2023
Merged

Add taxonomy block using SelectTree #39947

merged 15 commits into from
Aug 31, 2023

Conversation

nathanss
Copy link
Contributor
@nathanss nathanss commented Aug 29, 2023

Submission Review Guidelines:

Changes proposed in this Pull Request:

This creates a "Hierarchical Taxonomy" block, which will be firstly used for WooCommerce Brands plugin, and also replace woocommerce/product-category-field block in the future.

Part of #39206 .

How to test the changes in this Pull Request:

Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:

  1. Install the "Custom Post Type UI" plugin by WebDevStudios
  2. Set up some custom taxonomies.
    • Make sure to attach it to the Products post type
  3. Add code similar to the following to a plugin/mu-plugin file, to add the properties to the REST API response and request:
function YOUR_PREFIX_rest_api_prepare_custom1_to_product( $response, $post ) {
	$post_id = $post->get_id();

	if ( empty( $response->data[ 'custom1' ] ) ) {
		$terms = [];

		foreach ( wp_get_post_terms( $post_id, 'custom-taxonomy' ) as $term ) {
			$terms[] = [
				'id'   => $term->term_id,
				'name' => $term->name,
				'slug' => $term->slug,
			];
		}

		$response->data[ 'custom1' ] = $terms;
	}

	return $response;
}

add_filter( 'woocommerce_rest_prepare_product_object', 'YOUR_PREFIX_rest_api_prepare_custom1_to_product', 10, 2 );

function YOUR_PREFIX_rest_api_add_custom1_to_product( $product, $request, $creating = true ) {
	$product_id = $product->get_id();
	$params     = $request->get_params();
	$custom1s     = isset( $params['custom1'] ) ? $params['custom1'] : array();

	if ( ! empty( $custom1s ) ) {
		if ( $custom1s[0]['id'] ) {
			$custom1s = array_map(
				function ( $custom1 ) {
					return absint( $custom1['id'] );
				},
				$custom1s
			);
		} else {
			$custom1s = array_map( 'absint', $custom1s );
		}
		wp_set_object_terms( $product_id, $custom1s, 'custom-taxonomy' );
	}
}

add_filter( 'woocommerce_rest_insert_product_object', 'YOUR_PREFIX_rest_api_add_custom1_to_product', 10, 3 );
  1. Add a block for the taxonomy property, using code similar to the following:
$section_fields[] = [
	'woocommerce/taxonomy-field',
	[
		'slug'               => 'custom-taxonomy',
		'property' => 'custom1',
		'label'                                  => __( 'Custom Taxonomy', 'woocommerce' ),
		'createTitle'                        => __( 'Create new custom taxonomy', 'woocommerce' ),
	]
];

Changelog entry

  • Automatically create a changelog entry from the details below.

Significance

  • Patch
  • Minor
  • Major

Type

  • Fix - Fixes an existing bug
  • Add - Adds functionality
  • Update - Update existing functionality
  • Dev - Development related task
  • Tweak - A minor adjustment to the codebase
  • Performance - Address performance issues
  • Enhancement - Improvement to existing functionality

Message

Comment

@nathanss nathanss self-assigned this Aug 29, 2023
@github-actions
Copy link
Contributor
github-actions bot commented Aug 29, 2023

Test Results Summary

Commit SHA: 8c134f3

Test 🧪Passed ✅Failed 🚨Broken 🚧Skipped ⏭️Unknown ❔Total 📊Duration ⏱️
API Tests25900202611m 12s
E2E Tests1950015021016m 45s

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.

@mattsherman mattsherman self-requested a review August 29, 2023 18:29
@github-actions
Copy link
Contributor

Hi @mattsherman,

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:
https://github.com/woocommerce/woocommerce/wiki/Writing-high-quality-testing-instructions

Copy link
Contributor
@mattsherman mattsherman left a comment

Choose a reason for hiding this comment

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

Nice start on this @nathanss !

I need to take a closer look, but some initial thoughts...

  • Some testing instructions that don't depend on the brands PR/plugin would be good
  • Relatedly, it would be good to verify that this works with other custom taxonomies (I tried creating some with the "Custom Post Type UI" plugin, but I don't know why they don't seem to be appearing in the REST API responses (which I think might be the problem).
  • It would be ideal if this block automatically handled both hierarchical and non-hierarchical taxonomies. I would think that should be possible without too much hassle.

const [ selectedEntries, setSelectedEntries ] = useEntityProp< Taxonomy[] >(
'postType',
'product',
taxonomyNamePlural
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is actually not necessarily the plural version of the taxonomy name, but rather the name of the property used in the REST API.

margin-top: 36px;
display: flex;
flex-direction: row;
gap: 8px;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can use $gap-smaller

overflow: visible;

&__buttons {
margin-top: 36px;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can use $gap-larger

@nathanss
Copy link
Contributor Author

@mattsherman thx for the review!

Some testing instructions that don't depend on the brands PR/plugin would be good

I can't think of a good way of doing this. I don't know how using useEntityProp would work in another context, like storybook, for example. One other way would be to migrate the category field. But ultimately I think the best way of testing this is with the brands plugin for now, since it is the first use case. Do you have any suggestions?

Relatedly, it would be good to verify that this works with other custom taxonomies (I tried creating some with the "Custom Post Type UI" plugin, but I don't know why they don't seem to be appearing in the REST API responses (which I think might be the problem).

You're right, we need to have the property in the REST API. AFAIK we don't have any other property on the product to test this on for now.

It would be ideal if this block automatically handled both hierarchical and non-hierarchical taxonomies. I would think that should be possible without too much hassle.

I will work on that.

@mattsherman
Copy link
Contributor

@mattsherman thx for the review!

Some testing instructions that don't depend on the brands PR/plugin would be good

I can't think of a good way of doing this. I don't know how using useEntityProp would work in another context, like storybook, for example. One other way would be to migrate the category field. But ultimately I think the best way of testing this is with the brands plugin for now, since it is the first use case. Do you have any suggestions?

Ideally, I think testing one PR should not depend on changes in another PR. I have figured out how to test this without the Brands plugin (which is needed to test the non-hierarchical case too).

Relatedly, it would be good to verify that this works with other custom taxonomies (I tried creating some with the "Custom Post Type UI" plugin, but I don't know why they don't seem to be appearing in the REST API responses (which I think might be the problem).

You're right, we need to have the property in the REST API. AFAIK we don't have any other property on the product to test this on for now.

I figured out how to accomplish this.

It would be ideal if this block automatically handled both hierarchical and non-hierarchical taxonomies. I would think that should be possible without too much hassle.

I will work on that.

Thanks!

Okay, here is an approach I have figured out to test this easily...

  1. Install the "Custom Post Type UI" plugin by WebDevStudios (it's free; you really don't need it though... you could just register a taxonomy via code... I just used this to save a little bit of time/typing/learning when trying to get things working)
  2. Set up some custom taxonomies.
    • "Taxonomy Slug" is our "taxonomyName"
    • Make sure to attach it to the Products post type
  3. Add code similar to the following to a plugin/mu-plugin file, to add the properties to the REST API response:
function YOUR_PREFIX_rest_api_add_custom1_to_product( $response, $post ) {
	$post_id = $post->get_id();

	if ( empty( $response->data[ 'custom1' ] ) ) {
		$terms = [];

		foreach ( wp_get_post_terms( $post_id, 'custom-taxonomy' ) as $term ) {
			$terms[] = [
				'id'   => $term->term_id,
				'name' => $term->name,
				'slug' => $term->slug,
			];
		}

		$response->data[ 'custom1' ] = $terms;
	}

	return $response;
}

add_filter( 'woocommerce_rest_prepare_product_object', 'YOUR_PREFIX_rest_api_add_custom1_to_product', 10, 2 );
  1. Add a block for the taxonomy property, using code similar to the following (using pre-API technique just because we don't have template registration in quite yet):
$section_fields[] = [
	'woocommerce/taxonomy-field',
	[
		'taxonomyName'               => 'custom-taxonomy',
		'taxonomyNameOnEntity' => 'custom1',
		'label'                                  => __( 'Custom Taxonomy', 'woocommerce' ),
		'createTitle'                        => __( 'Create new custom taxonomy', 'woocommerce' ),
	]
];

Copy link
Contributor
@mattsherman mattsherman left a comment

Choose a reason for hiding this comment

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

Excellent iteration on this so far! Overall, things appear to be working pretty well with the latest changes. I will do a more rigorous final test and walk through the code once the remaining changes are made.

"type": "string",
"__experimentalRole": "content"
},
"taxonomyNameOnEntity": {
Copy link
Contributor

Choose a reason for hiding this comment

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

How about property? That's what other generic fields like our checkbox and radio button blocks use.

Comment on lines 27 to 26
"hierarchical": {
"type": "boolean",
"default": false,
"__experimentalRole": "content"
}
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 think the consumer should set this. We can determine this by querying for details on the taxonomy.

"keywords": [ "taxonomy"],
"textdomain": "default",
"attributes": {
"taxonomyName": {
Copy link
Contributor

Choose a reason for hiding this comment

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

@nathanss nathanss changed the title Add hierarchical taxonomy block Add taxonomy block using SelectTree Aug 30, 2023
@nathanss
Copy link
Contributor Author

@mattsherman Awesome review, thanks a lot.

I updated the code with the suggested changes. I also updated the PR title and description, since it evolved a lot since the beginning. Can you check again?

@nathanss nathanss force-pushed the add/hierarchical-taxonomy branch from 3df9767 to ce9f2f3 Compare August 30, 2023 18:25
@nathanss nathanss requested a review from mattsherman August 30, 2023 19:09
@nathanss nathanss force-pushed the add/hierarchical-taxonomy branch from ce9f2f3 to d7805ce Compare August 30, 2023 19:35
@mattsherman
Copy link
Contributor

Note: forgot that we have to handle setting the taxonomy in the REST request as well... updated the testing instructions to account for that.

Copy link
Contributor
@mattsherman mattsherman left a comment

Choose a reason for hiding this comment

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

Testing seems to work pretty well with the brands taxonomy, as well as two custom taxonomies I created, one hierarchical, one flat (after I added the handling to save the taxonomy in the REST handler*).

The main issue I ran into during testing was that the parent dropdown in the modal does not show parents hierarchically.

* I suppose that this generic taxonomy block only works out of the box if the custom taxonomy developer has implemented support for the REST API as is being done for brands and categories (same shape of data for the property). We'll have to document this. I think it is a reasonable limitation, and maybe one we can extend over time if there are other patterns.

"name": "woocommerce/taxonomy-field",
"title": "Taxonomy",
"category": "widgets",
"description": "A block that displays a taxonomy field, allowing to search, select, and create new entries",
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion...

"A block that displays a taxonomy field, allowing searching, selection, and creation of new items"

const hierarchical = useSelect( ( select ) => {
const taxonomyDetails = select( 'core' ).getTaxonomy(
attributes.slug
// eslint-disable-next-line @typescript-eslint/no-explicit-any
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 avoid this?

Copy link
Contributor
@mattsherman mattsherman left a comment

Choose a reason for hiding this comment

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

Nice work on this, @nathanss -- latest changes look good! :shipit:

@nathanss nathanss merged commit 501abc4 into trunk Aug 31, 2023
@nathanss nathanss deleted the add/hierarchical-taxonomy branch August 31, 2023 18:19
@github-actions github-actions bot added this to the 8.2.0 milestone Aug 31, 2023
@github-actions github-actions bot added the needs: analysis Indicates if the PR requires a PR testing scrub session. label Aug 31, 2023
@lanej0 lanej0 added status: analysis complete Indicates if a PR has been analysed by Solaris and removed needs: analysis Indicates if the PR requires a PR testing scrub session. labels Aug 31, 2023
@octaedro octaedro mentioned this pull request Sep 7, 2023
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: analysis complete Indicates if a PR has been analysed by Solaris
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0