Make WordPress Core


Ignore:
Timestamp:
07/15/2026 04:25:35 AM (8 weeks ago)
Author:
wildworks
Message:

Icons: Add APIs for collection and icon registration

Introduces a set of public APIs for registering icon collections and individual icons, allowing themes and plugins to register icons for consistent use across the block editor and the wider WordPress admin.

  • Add the WP_Icon_Collections_Registry class, a singleton that manages the registration of icon collections. Each collection groups a set of icons under a namespace and is exposed through the REST API via the new WP_REST_Icon_Collections_Controller.
  • Update the WP_Icons_Registry class to allow registering custom icons through public register() and unregister() methods, surfaced through WP_REST_Icons_Controller.
  • Add four wrapper functions in icons.php: wp_register_icon_collection() and wp_unregister_icon_collection() for collections, and wp_register_icon() and wp_unregister_icon() for individual icons.
  • Register the default collections and icons through _wp_register_default_icon_collections() and _wp_register_default_icons(), both hooked to the init action.

Props mcsf, tyxla, wildworks.
See #64847.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-icons-controller.php

    r62435 r62748  
    11<?php
     2
    23/**
    34 * REST API: WP_REST_Icons_Controller class
     
    1011/**
    1112 * Controller which provides a REST endpoint for the editor to read registered
    12  * icons. For the time being, only core icons are available, which are defined
    13  * in a single manifest file (wp-includes/assets/icon-library-manifest.php).
    14  * Icons are comprised of their SVG source, a name and a translatable label.
     13 * icons. Icons are grouped into collections (the default one being `core`).
    1514 *
    1615 * @since 7.0.0
     
    3433         *
    3534         * @since 7.0.0
     35         * @since 7.1.0 Added the `/icons/<collection>` collection-scoped route.
    3636         */
    3737        public function register_routes() {
     
    5252                register_rest_route(
    5353                        $this->namespace,
    54                         '/' . $this->rest_base . '/(?P<name>[a-z][a-z0-9-]*/[a-z][a-z0-9-]*)',
     54                        '/' . $this->rest_base . '/(?P<collection>[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)',
     55                        array(
     56                                'args'   => array(
     57                                        'collection' => array(
     58                                                'description' => __( 'Icon collection slug.' ),
     59                                                'type'        => 'string',
     60                                        ),
     61                                ),
     62                                array(
     63                                        'methods'             => WP_REST_Server::READABLE,
     64                                        'callback'            => array( $this, 'get_items' ),
     65                                        'permission_callback' => array( $this, 'get_items_permissions_check' ),
     66                                        'args'                => $this->get_collection_params(),
     67                                ),
     68                                'schema' => array( $this, 'get_public_item_schema' ),
     69                        )
     70                );
     71
     72                register_rest_route(
     73                        $this->namespace,
     74                        '/' . $this->rest_base . '/(?P<name>[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?/[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)',
    5575                        array(
    5676                                'args'   => array(
     
    120140
    121141        /**
    122          * Retrieves all icons.
    123          *
    124          * @since 7.0.0
     142         * Retrieves all icons, optionally scoped to a collection.
     143         *
     144         * @since 7.0.0
     145         * @since 7.1.0 Supports filtering by collection.
    125146         *
    126147         * @param WP_REST_Request $request Full details about the request.
     
    128149         */
    129150        public function get_items( $request ) {
     151                $collection = $request->get_param( 'collection' );
     152
     153                if ( null !== $collection && ! WP_Icon_Collections_Registry::get_instance()->is_registered( $collection ) ) {
     154                        return new WP_Error(
     155                                'rest_icon_collection_not_found',
     156                                sprintf(
     157                                        /* translators: %s: Icon collection slug. */
     158                                        __( 'Icon collection not found: "%s".' ),
     159                                        $collection
     160                                ),
     161                                array( 'status' => 404 )
     162                        );
     163                }
     164
    130165                $response = array();
    131166                $search   = $request->get_param( 'search' );
    132167                $icons    = WP_Icons_Registry::get_instance()->get_registered_icons( $search );
     168
    133169                foreach ( $icons as $icon ) {
     170                        if ( null !== $collection && ( ! isset( $icon['collection'] ) || $icon['collection'] !== $collection ) ) {
     171                                continue;
     172                        }
    134173                        $prepared_icon = $this->prepare_item_for_response( $icon, $request );
    135174                        $response[]    = $this->prepare_response_for_collection( $prepared_icon );
     
    187226         *
    188227         * @since 7.0.0
     228         * @since 7.1.0 Added the `collection` field.
    189229         *
    190230         * @param array           $item    Raw icon as registered, before any changes.
     
    195235                $fields = $this->get_fields_for_response( $request );
    196236                $keys   = array(
    197                         'name'    => 'name',
    198                         'label'   => 'label',
    199                         'content' => 'content',
     237                        'name'       => 'name',
     238                        'label'      => 'label',
     239                        'content'    => 'content',
     240                        'collection' => 'collection',
    200241                );
    201242                $data   = array();
     
    216257         *
    217258         * @since 7.0.0
     259         * @since 7.1.0 Added the `collection` property.
    218260         *
    219261         * @return array Item schema data.
     
    229271                        'type'       => 'object',
    230272                        'properties' => array(
    231                                 'name'    => array(
     273                                'name'       => array(
    232274                                        'description' => __( 'The icon name.' ),
    233275                                        'type'        => 'string',
     
    235277                                        'context'     => array( 'view', 'edit', 'embed' ),
    236278                                ),
    237                                 'label'   => array(
     279                                'label'      => array(
    238280                                        'description' => __( 'The icon label.' ),
    239281                                        'type'        => 'string',
     
    241283                                        'context'     => array( 'view', 'edit', 'embed' ),
    242284                                ),
    243                                 'content' => array(
     285                                'content'    => array(
    244286                                        'description' => __( 'The icon content (SVG markup).' ),
    245287                                        'type'        => 'string',
     
    247289                                        'context'     => array( 'view', 'edit', 'embed' ),
    248290                                ),
     291                                'collection' => array(
     292                                        'description' => __( 'The slug of the collection this icon belongs to.' ),
     293                                        'type'        => 'string',
     294                                        'readonly'    => true,
     295                                        'context'     => array( 'view', 'edit', 'embed' ),
     296                                ),
    249297                        ),
    250298                );
     
    259307         *
    260308         * @since 7.0.0
     309         * @since 7.1.0 Added the `collection` parameter.
    261310         *
    262311         * @return array Collection parameters.
     
    265314                $query_params                       = parent::get_collection_params();
    266315                $query_params['context']['default'] = 'view';
     316                $query_params['collection']         = array(
     317                        'description' => __( 'Limit results to icons belonging to the given collection slug.' ),
     318                        'type'        => 'string',
     319                        'pattern'     => '^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$',
     320                );
    267321                return $query_params;
    268322        }
Note: See TracChangeset for help on using the changeset viewer.