Make WordPress Core


Ignore:
Timestamp:
05/31/2024 01:17:50 AM (12 months ago)
Author:
noisysocks
Message:

Block Themes: Add support for relative URLs in top-level theme.json styles

Allow using relative file: URLs in top-level theme.json properties such as
styles.background, and modify the REST API to provide clients with the
absolute URLs via a 'https://api.w.org/theme-file' attribute in the _links
array.

Props ramonopoly.
Fixes #61273.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-theme-json-resolver.php

    r58185 r58262  
    745745        return $variations;
    746746    }
     747
     748    /**
     749     * Resolves relative paths in theme.json styles to theme absolute paths
     750     * and returns them in an array that can be embedded
     751     * as the value of `_link` object in REST API responses.
     752     *
     753     * @since 6.6.0
     754     *
     755     * @param WP_Theme_JSON  $theme_json A theme json instance.
     756     * @return array An array of resolved paths.
     757     */
     758    public static function get_resolved_theme_uris( $theme_json ) {
     759        $resolved_theme_uris = array();
     760
     761        if ( ! $theme_json instanceof WP_Theme_JSON ) {
     762            return $resolved_theme_uris;
     763        }
     764
     765        $theme_json_data = $theme_json->get_raw_data();
     766
     767        // Top level styles.
     768        $background_image_url = isset( $theme_json_data['styles']['background']['backgroundImage']['url'] ) ? $theme_json_data['styles']['background']['backgroundImage']['url'] : null;
     769
     770        /*
     771         * The same file convention when registering web fonts.
     772         * See: WP_Font_Face_Resolver:: to_theme_file_uri.
     773         */
     774        $placeholder = 'file:./';
     775        if (
     776            isset( $background_image_url ) &&
     777            is_string( $background_image_url ) &&
     778            // Skip if the src doesn't start with the placeholder, as there's nothing to replace.
     779            str_starts_with( $background_image_url, $placeholder )
     780        ) {
     781            $file_type          = wp_check_filetype( $background_image_url );
     782            $src_url            = str_replace( $placeholder, '', $background_image_url );
     783            $resolved_theme_uri = array(
     784                'name'   => $background_image_url,
     785                'href'   => sanitize_url( get_theme_file_uri( $src_url ) ),
     786                'target' => 'styles.background.backgroundImage.url',
     787            );
     788            if ( isset( $file_type['type'] ) ) {
     789                $resolved_theme_uri['type'] = $file_type['type'];
     790            }
     791            $resolved_theme_uris[] = $resolved_theme_uri;
     792        }
     793
     794        return $resolved_theme_uris;
     795    }
     796
     797    /**
     798     * Resolves relative paths in theme.json styles to theme absolute paths
     799     * and merges them with incoming theme JSON.
     800     *
     801     * @since 6.6.0
     802     *
     803     * @param WP_Theme_JSON  $theme_json A theme json instance.
     804     * @return WP_Theme_JSON Theme merged with resolved paths, if any found.
     805     */
     806    public static function resolve_theme_file_uris( $theme_json ) {
     807        $resolved_urls = static::get_resolved_theme_uris( $theme_json );
     808        if ( empty( $resolved_urls ) ) {
     809            return $theme_json;
     810        }
     811
     812        $resolved_theme_json_data = array(
     813            'version' => WP_Theme_JSON::LATEST_SCHEMA,
     814        );
     815
     816        foreach ( $resolved_urls as $resolved_url ) {
     817            $path = explode( '.', $resolved_url['target'] );
     818            _wp_array_set( $resolved_theme_json_data, $path, $resolved_url['href'] );
     819        }
     820
     821        $theme_json->merge( new WP_Theme_JSON( $resolved_theme_json_data ) );
     822
     823        return $theme_json;
     824    }
    747825}
Note: See TracChangeset for help on using the changeset viewer.