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

Allow adding new categories in Editor UI #123

Merged
merged 64 commits into from
Jun 16, 2023

Conversation

mike-day
Copy link
Contributor

@mike-day mike-day commented Mar 23, 2023

This PR allows the registration of custom pattern categories from within the editor UI.

Add a new category by simply typing in the categories dropdown.

Note: this PR should probably not be merged until #175, #177, and #180 are merged.


Registration is done in the pattern file itself, with the registration calls added just below the pattern header:

Screenshot 2023-05-09 at 3 04 33 PM

Using this method is almost akin to each pattern file being kind of like its own tiny plugin, with no patterns relying on each other for registration and each remaining their own source of truth.

Comment on lines 418 to 420
$formatted_registration_string = "if ( function_exists( 'register_block_pattern_category' ) ) {
" . implode( "\n ", $custom_category_registrations ) . '
}';
Copy link
Contributor Author

@mike-day mike-day Mar 23, 2023

Choose a reason for hiding this comment

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

Same here — this is ugly but should allow linting to pass for the user.

Copy link
Contributor

@kienstra kienstra Mar 23, 2023

Choose a reason for hiding this comment

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

Is there any time register_block_pattern_category() isn't defined?

It was introduced in WP 5.5.0.

Though maybe its file wasn't included when this code runs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good question!

My thinking was that we can't really know what version of WP an end-user of the theme might be using, but it's possible that we don't need to even worry about it.

Copy link
Contributor

@kienstra kienstra Mar 23, 2023

Choose a reason for hiding this comment

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

Yeah, if it's only a question of the WP version, I think we can assume they have 5.5 or later.

PM requires 6.2 (though even then, it shouldn't require 6.2, as it's not released).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems like register_block_pattern was also introduced in 5.5.

Maybe it's worth investigating if the patterns directory is even checked for versions older than that. If they aren't, there is no reason to leave this check imo.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Upon investigating this further by testing with 5.4.12 — the registration block should not need to check that either WP_Block_Pattern_Categories_Registry or register_block_pattern_category() exists before calling them.

Both were introduced in WP 5.5, and previous versions of WP do not glob the patterns folder in a given theme.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good find!

Copy link
Contributor

@kienstra kienstra left a comment

Choose a reason for hiding this comment

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

Hi @mike-day,
This approach looks good. It'd be nice to simplify the JS logic if possible, but this is a high-level review.

Pro

  • Single source of truth (PHP file). That's a huge plus.
  • This works even without PM active, like you showed.
  • By registering the custom category in the pattern's PHP file, a custom category only has to know about its own custom categories. If we registered all custom categories in a categories.php file, we'd have to tree shake unused categories after every save. It'd be much more complex.

Con

  • The JS logic here is really complex and untestable. Maybe it's too early to judge that, though 😄
  • Every pattern a user edits will have a 'Custom Categories' value in the header, even if they didn't add one. They might wonder why. Still, we could work on avoiding that.

Screenshot 2023-03-23 at 12 47 02 PM

@mike-day
Copy link
Contributor Author

mike-day commented Mar 23, 2023

Great feedback, @kienstra!

As for Custom Categories always being added to the header — what would you think about it just being removed if there are no selections present? The registration statements are already removed, so it could make sense to remove it from the header as well since it's not something WordPress will recognize anyway.

@kienstra
Copy link
Contributor

Great feedback, @kienstra!

As for Custom Categories always being added to the header — what would you think about it just being removed if there are selections present? The registration statements are already removed, so it could make sense to remove it from the header as well since it's not something WordPress will recognize anyway.

Yeah, that sounds good.

It's only a minor criticism. We could also refactor how we output the pattern file headers.

@mike-day
Copy link
Contributor Author

@kienstra the Custom Categories header is rendered conditionally with 8771720.

@kienstra
Copy link
Contributor

kienstra commented Mar 23, 2023

Hi @mike-day,
8771720 looks good. Maybe later we can consider doing something similar for other optional header values, but that's another discussion.

@kienstra
Copy link
Contributor

kienstra commented Mar 23, 2023

Are you ready for feedback on whether this should check whether a category is already registered, and conditionally register it? (Not implementation details, but the idea of whether it should have a conditional.)

Don't want to nitpick if it's too early.

@mike-day mike-day changed the title Allow adding new categories in Editor UI [DO NOT MERGE] Allow adding new categories in Editor UI Mar 24, 2023
@mike-day
Copy link
Contributor Author

Are you ready for feedback on whether this should check whether a category is already registered, and conditionally register it? (Not implementation details, but the idea of whether it should have a conditional.)

Don't want to nitpick if it's too early.

It might be a bit early! I just tried building from this PR to use a utility file instead of inserting registration calls in the pattern file with #124.

We also might want to try Mike's idea as an alternative as well.

My thought is that we can try a few proof-of-concept methods like this to gauge if it's worth pursuing custom category registration at all — it's going to add complexity to the app no matter what.

@kienstra
Copy link
Contributor

It might be a bit early! I just tried building from this PR to use a utility file instead of inserting registration calls in the pattern file with #124.

Sounds good!

@mike-day
Copy link
Contributor Author

mike-day commented Mar 24, 2023

@kienstra I made a few small changes (including using a prepend with the new category name instead of meta — it wasn't working consistently that way).

Let's get into the conversation around checking against the category registry!


We don't really need to check against the registry. Core will only register a given pattern category once, regardless of how many times that call is made. We could get rid of some boilerplate if we didn't make that check.

On the other hand, it's hard to know whether that behavior in core is a feature or a bug.

Otherwise, it does feel "right" to me to conditionally register, but I can't really articulate why.

@kienstra
Copy link
Contributor

That's a good point. Let me think about this.

@mike-day
Copy link
Contributor Author

mike-day commented Mar 25, 2023

Looking at the register() method in the block pattern category registry, it seems that there is no logic to check if an incoming category is already registered.

Instead, if the name of the new category matches an existing category, the existing category is simply overwritten:

$category = array_merge(
	array( 'name' => $category_name ),
	$category_properties
);

$this->registered_categories[ $category_name ] = $category;

So, while it initially appears that register_block_pattern_category() call be called with the same $category_name any number of times and only register the category once, the new category is actually being registered/overwritten repeatedly.

Copy link
Contributor

@kienstra kienstra left a comment

Choose a reason for hiding this comment

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

Hi @mike-day,
The tests look really good. Very good coverage, and good work extracting into pure functions.

( matchedCategory ) =>
matchedCategory.value === category
)
value={ getSelectedOptions(
Copy link
Contributor

Choose a reason for hiding this comment

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

Really nice extraction to a pure function

wp-modules/pattern-data-handlers/pattern-data-handlers.php Outdated Show resolved Hide resolved
wp-modules/pattern-data-handlers/pattern-data-handlers.php Outdated Show resolved Hide resolved
/**
* Tests maybe_add_custom_category_header.
*/
public function test_maybe_add_custom_category_header() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice test. It's simple, but covers the 2 important cases: where there is a header, and there isn't.

$this->normalize( create_formatted_category_registrations( $custom_categories ) ),
);

$this->assertEmpty( create_formatted_category_registrations( [] ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

Another nice test. It's simple, and covers the main cases.


return $custom_category_registrations;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

In a future PR, let's split this file into another. It's getting long.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed — we could clean up this file dramatically by splitting things up.

[ 'Second Category', 'Third Category' ],
],
] )(
'should get the custom categories created by Pattern Manager',
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice test coverage, from [], to matched categories that don't have pm_custom, to matched categories that do have pm_custom.

Copy link
Contributor

@kienstra kienstra left a comment

Choose a reason for hiding this comment

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

Hi @mike-day,
The tests look really good. Very good coverage, and good work extracting into pure functions.

@mike-day mike-day marked this pull request as ready for review June 1, 2023 19:09
@johnstonphilip
Copy link
Contributor

johnstonphilip commented Jun 1, 2023

This is really impressive @mike-day!

I've found a bug which we might want to fix. The desired intention is that custom categories registered in a theme do not get written to a pattern file. But they do in this scenario:

  1. Add a custom category to a pattern using the UI
  2. Now, register that category in your theme.
  3. Re-save the original pattern, notice the custom category registration does not get stripped out of the file

I think to fix this, we'll need to add some logic to the get_pattern_by_path to double check for custom category existence, and strip them out there if so.

@johnstonphilip
Copy link
Contributor

johnstonphilip commented Jun 1, 2023

Upon digging into this, it's a bit harder than I first thought. Because pattern files are actually being included in format_pattern_data, it means all pattern categories are registered before we save, so we don't have a reliable way of knowing if a pattern category was registered from the theme's functions file, or the pattern file itself.

Copy link
Contributor

@johnstonphilip johnstonphilip left a comment

Choose a reason for hiding this comment

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

Since trying to prevent category registration has only cosmetic benefits right now, I think we can merge this as-is.

@kienstra
Copy link
Contributor

Sorry, I accidentally merged #199. Reverting now.

@kienstra
Copy link
Contributor

Sorry, I won't commit to this PR anymore. Just wanted to undo my accidental merge of #199.

@mike-day mike-day merged commit f2a7b26 into main Jun 16, 2023
@mike-day mike-day deleted the try/add-new-categories-in-editor-ui branch June 16, 2023 17:28
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants