Icons API: Support searching in labels; extend classes post-7.0 work#75878
Icons API: Support searching in labels; extend classes post-7.0 work#75878
Conversation
t-hamano
left a comment
There was a problem hiding this comment.
Thanks for working on this!
The body of Gutenberg_Icons_Registry_7_1 illustrates the downside of keeping most classes in WP_Icons_Registry and WP_REST_Icons_Controller private: almost everything needs to be redefined in the extended classp.
If we used
protectedinstead, only the following would really need to be defined in Gutenberg_Icons_Registry_7_1:
Many of the methods will likely become public in the future, so changing them to protected should be fine.
Another approach would be to create a complete copy of the registry and controller for Gutenberg. This is already done for some classes and APIs. So, the configuration would look something like this:
lib/
├ class-wp-icons-registry-gutenberg.php
└ class-wp-rest-icons-controller-gutenberg.php
Theendpoints will always be overridden with the Gutenberg version, like this.
// lib/rest-api.php
function gutenberg_register_icon_controller_endpoints() {
$icons_registry = new WP_REST_Icons_Controller_Gutenberg();
$icons_registry->register_routes();
}
add_action( 'rest_api_init', 'gutenberg_register_icon_controller_endpoints' );What do you think?
The only thing I can't solve is that registry overrides only take effect within the endpoint.
So, different registries are referenced when using the WP_Icons_Registry class directly and when referencing the wp/v2/icons endpoint. I can't think of a good way to solve this right now 🤔
[…]
Either way seems fine to me. :) In theory the
Right, exactly! Same question here. So I did notice that, if the base class has everything class Gutenberg_Foo extends WP_Foo {
public static hijack_instance() {
self::$instance = new self();
}
}
Gutenberg_Foo::hijack_instance();
echo WP_Foo::get_instance() === Gutenberg_Foo::get_instance(); // 1… but this is very hacky. I don't know what unintended consequences it may have. The other hacky way is using PHP reflection. Finally, the least hacky way is to introduce a filter and do as we do in function parse_blocks( $content ) {
$parser_class = apply_filters( 'block_parser_class', 'WP_Block_Parser' );
$parser = new $parser_class();
return $parser->parse( $content );
}Should we aim to do the latter during this Beta cycle? Am I looking at things the wrong way? Let me know. :) |
Sorry, I still don't understand this approach 🤔 If we were to apply this approach to the icon registry, what would the code look like specifically? |
Maybe by adding a filter inside |
Make it easier to iterate on this class in Gutenberg via class extension. See proof of concept and discussion in: WordPress/gutenberg#75878 Follow-up to [61674]. Props mcsf. See #64651. git-svn-id: https://develop.svn.wordpress.org/trunk@61748 602fd350-edb4-49c9-b593-d223f7449a82
Make it easier to iterate on this class in Gutenberg via class extension. See proof of concept and discussion in: WordPress/gutenberg#75878 Follow-up to [61674]. Props mcsf. See #64651. Built from https://develop.svn.wordpress.org/trunk@61748 git-svn-id: http://core.svn.wordpress.org/trunk@61054 1a063a9b-81f0-0310-95a4-ce76da25c4cd
lib/compat/wordpress-7.1/class-gutenberg-icons-registry-7-1.php
Outdated
Show resolved
Hide resolved
| /** | ||
| * Modified to point $manifest_path at Gutenberg packages | ||
| */ | ||
| protected function __construct() { |
There was a problem hiding this comment.
P.S. I plan to move all the code in the constructor to a hook in the future, so that Gutenbeg can easily override the core icons.
It will probably look something like this. What do you think?
// Probably in WordPress 7.1
function _register_core_icons() {
$icons_directory = __DIR__ . '/icons/';
// ...
}
add_action( 'init', '_register_core_icons' );
// On the Gutenberg plugin side, remove the core hook and re-register the core icon
remove_action( 'init', '_register_core_icons' );
add_action( 'init', '_gutenberg_register_core_icons' );
function _gutenberg_register_core_icons() {
// In WordPress 7.0, the core icon registration process is hard-coded
// in the constructor, so we will explicitly unregister all of them here.
$all_icons = WP_Icons_Registry::get_instance()->get_registered_icons();
foreach ( $all_icons as $icon ) {
WP_Icons_Registry::get_instance()->unregister( $icon['name'] );
}
// Re-register core icons using assets from Gutenberg
$icons_directory = __DIR__ . '/../../../packages/icons/src/';
// ...
}There was a problem hiding this comment.
I think that would be alright. Assuming that we'll be ready to make ::register public in 7.1, we won't be as concerned with the exposure that this hook would entail. :)
In this proof of concept, we enhance the Icons registry via compat classes to: - Also search within icon labels, not just icon names - Point at Gutenberg's own manifest.php file rather than Core's - Edit the label of icon `core/table` to "Table Verse" in order to test searching for "verse" (which should return `core/verse` and `core/table`). The body of Gutenberg_Icons_Registry_7_1 illustrates the downside of keeping most classes in WP_Icons_Registry and WP_REST_Icons_Controller private: almost everything needs to be redefined in the extended classp. If we used `protected` instead, only the following would really need to be defined in Gutenberg_Icons_Registry_7_1: - __construct: to point to the new manifest.php - get_registered_icons: to extend searching to labels - get_instance and $instance: to break away from the base class But currently we need to add the following: - register - get_content - sanitize_icon_content - get_registered_icon - is_registered
Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com>
2a10e49 to
35adbd3
Compare
|
@mcsf What do you think about shipping this PR? I think it might be less disruptive to ship this PR before moving forward with the following PR: |
|
Flaky tests detected in 4445a89. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/22957926576
|
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
I'll refresh it to account for the change from |
|
Having synced and trimmed the classes and added a test case, I edited the PR title, description and commit message. Feel free to comment or follow up if I missed anything. :) |
|
I opened a core ticket to ensure that all iterations added in Gutenberg are properly backported to core. |
What?
Enhance the Icons registry via compat classes to:
This PR started as a prototype to gauge what would be needed for future extensibilty. Through it, we've already switched the visibilty of the methods and attributes in Core's WP_Icons_Registry from
privatetoprotected. Thanks to that, class extension is much simpler (1b9874e). See the edit history of this PR description for more.Why?
How?
Gutenberg_Icons_Registry_7_1$instanceandget_instance()to avoid conflicting with the base registry classGutenberg_REST_Icons_Controller_7_1Gutenberg_Icons_Registry_7_1instead ofWP_Icons_Registryrest_api_initwith low priority to letGutenberg_REST_Icons_Controller_7_1override the REST routes registered by the base classTesting Instructions
/wp/v2/icons?search=%score/at-symbol