Skip to content
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

Webfonts: enqueue fonts listed in theme.json #39988

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6dddb53
Register webfonts declared in theme.json
zaguiini Apr 4, 2022
d80dba4
Add registered webfonts to theme.json
zaguiini Apr 5, 2022
0d64aab
Enqueue webfonts listed in theme.json
zaguiini Apr 5, 2022
b527cd7
Do not run gutenberg_add_registered_webfonts_to_theme_json unless ope…
zaguiini Apr 7, 2022
62e0e6d
Extract utility functions into their own help files
zaguiini Apr 7, 2022
9c2c42b
Escape font face attributes when echoing errors
zaguiini Apr 7, 2022
1f63722
Add tests
zaguiini Apr 8, 2022
c89e70d
Inline gutenberg_map_font_family_indexes
zaguiini Apr 13, 2022
de27be0
Make array key transformation functions more generic
zaguiini Apr 13, 2022
3c1c444
Make helper functions used in Webfonts API private
zaguiini Apr 13, 2022
ed7e81c
Rename _gutenberg_register_webfonts_from_theme_json function
aristath Apr 18, 2022
a7d7c51
function_exists condition for _wp_register_webfonts_from_theme_json
aristath Apr 18, 2022
5caadad
Rename _gutenberg_enqueue_webfonts_listed_in_theme_json function
aristath Apr 18, 2022
c5a5b2b
Add function_exists check for _wp_enqueue_webfonts_listed_in_theme_json
aristath Apr 18, 2022
6a59c6c
Rename _gutenberg_add_registered_webfonts_to_theme_json function
aristath Apr 18, 2022
182507b
Add function_exists check for _wp_add_registered_webfonts_to_theme_json
aristath Apr 18, 2022
7f13181
Fix registering webfonts from styles variations
aristath Apr 18, 2022
0319d5b
Update lib/experimental/register-webfonts-from-theme-json.php
aristath Apr 19, 2022
ef407bd
Update lib/experimental/add-registered-webfonts-to-theme-json.php
aristath Apr 19, 2022
658b6ee
Rename unregister_font_family to remove_font_family
aristath Apr 19, 2022
bea59de
Update lib/experimental/webfonts-utils.php
aristath Apr 19, 2022
f55f4da
This has changed
aristath Apr 19, 2022
ae4238f
fix indentation
aristath Apr 19, 2022
dc14844
Fixes undefined index notice in _gutenberg_is_webfont_equal().
hellofromtonya Apr 19, 2022
bd4259e
Uses each `fontFaces` font-family for enqueuing.
hellofromtonya Apr 19, 2022
01abcde
Fixes failing test and updates test for Core coding standards.
hellofromtonya Apr 19, 2022
39d88e5
Prepped to WP Core coding standards.
hellofromtonya Apr 19, 2022
b36c647
Revert "Update lib/experimental/webfonts-utils.php"
aristath Apr 20, 2022
d6bbb43
Mark functions as private
aristath Apr 20, 2022
779cece
missed this one
aristath Apr 20, 2022
606373b
prefix stylesheet handles with 'wp-'
aristath Apr 20, 2022
1c0e508
Rename function to _wp_resolve_font_face_uri
aristath Apr 20, 2022
260156a
we don't need a separate function is_webfont_equal
aristath Apr 20, 2022
b2eb078
move find_webfont function to the WP_Webfonts class
aristath Apr 20, 2022
0de1117
The _wp_resolve_font_face_uri function is only used once. Can be removed
aristath Apr 20, 2022
e2fe01c
The array_keys_to_camel_case function can be removed
aristath Apr 20, 2022
e94fffa
Remove the _gutenberg_is_externally_registered_webfont function
aristath Apr 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions lib/experimental/add-registered-webfonts-to-theme-json.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php
/**
* Extend theme.json with programmatically registered webfonts.
*
* @package gutenberg
*/

if ( ! function_exists( '_wp_add_registered_webfonts_to_theme_json' ) ) {
/**
* Add missing webfonts data to the global styles.
*
* @since 6.0.0
* @private
*
* @param array $data The global styles.
* @return array The global styles with missing webfonts data.
*/
function _wp_add_registered_webfonts_to_theme_json( array $data ) {
$registered_font_families = wp_webfonts()->get_all_webfonts();

if ( empty( $registered_font_families ) ) {
return $data;
}

// Make sure the path to settings.typography.fontFamilies.theme exists
// before adding missing fonts.
if ( empty( $data['settings'] ) ) {
$data['settings'] = array();
}
if ( empty( $data['settings']['typography'] ) ) {
$data['settings']['typography'] = array();
}
if ( empty( $data['settings']['typography']['fontFamilies'] ) ) {
$data['settings']['typography']['fontFamilies'] = array();
}

/*
* Map the font families by slug to their corresponding index
* in theme.json, so we can avoid looping theme.json looking for
* font families every time we want to register a face.
*/
$font_family_indexes_in_theme_json = array();

foreach ( $data['settings']['typography']['fontFamilies'] as $index => $family ) {
$font_family_indexes_in_theme_json[ wp_webfonts()->get_font_slug( $family ) ] = $index;
}

/**
* Transforms the keys in the given array to camelCase.
*
* @param array $to_transform The array to transform.
* @return array Given array with camelCase keys.
*/
$array_keys_to_camel_case = function( array $to_transform ) {
$camel_cased_array = array();

foreach ( $to_transform as $key => $value ) {
$camel_cased_array[ lcfirst( str_replace( '-', '', ucwords( $key, '-' ) ) ) ] = $value;
}

return $camel_cased_array;
};

foreach ( $registered_font_families as $slug => $registered_font_faces ) {
// Font family not in theme.json, so let's add it.
if ( ! isset( $font_family_indexes_in_theme_json[ $slug ] ) ) {
$family_name = $registered_font_faces[0]['font-family'];

$data['settings']['typography']['fontFamilies'][] = array(
'origin' => 'gutenberg_wp_webfonts_api',
'fontFamily' => str_contains( $family_name, ' ' ) ? "'{$family_name}'" : $family_name,
'name' => $family_name,
'slug' => $slug,
'fontFaces' => array_map(
function( $font_face ) use ( $array_keys_to_camel_case ) {
$font_face['origin'] = 'gutenberg_wp_webfonts_api';

return $array_keys_to_camel_case( $font_face );
},
$registered_font_faces
),
);

continue;
}

$font_family_index_in_theme_json = $font_family_indexes_in_theme_json[ $slug ];
$font_family_in_theme_json = $data['settings']['typography']['fontFamilies'][ $font_family_index_in_theme_json ];

if ( ! isset( $font_family_in_theme_json['fontFaces'] ) ) {
// Font family exists, but it's not declaring any font face
// Let's not get in their way.
continue;
}

$font_faces_in_theme_json = $font_family_in_theme_json['fontFaces'];

foreach ( $registered_font_faces as $registered_font_face ) {
$registered_font_face = $array_keys_to_camel_case( $registered_font_face );

if ( false !== wp_webfonts()->find_webfont( $font_faces_in_theme_json, $registered_font_face ) ) {
// Webfont is already there, so let's not add it.
continue;
}

$registered_font_face['origin'] = 'gutenberg_wp_webfonts_api';

$data['settings']['typography']['fontFamilies'][ $font_family_index_in_theme_json ]['fontFaces'][] = $registered_font_face;
}
}

return $data;
}
}
43 changes: 39 additions & 4 deletions lib/experimental/class-wp-theme-json-resolver-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,23 @@ public static function get_theme_data( $deprecated = array(), $settings = array(
if ( null === static::$theme ) {
$theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json' ) );
$theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) );
$theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $theme_json_data );
static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data );

$original_theme_json = new WP_Theme_JSON_Gutenberg( $theme_json_data );
_wp_register_webfonts_from_theme_json( $original_theme_json->get_settings() );

if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
$theme_json_data = _wp_add_registered_webfonts_to_theme_json( $theme_json_data );
}

static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data );

if ( wp_get_theme()->parent() ) {
// Get parent theme.json.
$parent_theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json', true ) );
$parent_theme_json_data = static::translate( $parent_theme_json_data, wp_get_theme()->parent()->get( 'TextDomain' ) );
$parent_theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $parent_theme_json_data );
$parent_theme = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data );

$parent_theme = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data );
_wp_register_webfonts_from_theme_json( $parent_theme->get_settings() );

// Merge the child theme.json into the parent theme.json.
// The child theme takes precedence over the parent.
Expand Down Expand Up @@ -98,4 +106,31 @@ public static function get_theme_data( $deprecated = array(), $settings = array(
return $with_theme_supports;
}

/**
* There are three sources of data (origins) for a site:
* default, theme, and custom. The custom's has higher priority
* than the theme's, and the theme's higher than defaults's.
*
* Unlike the getters {@link get_core_data},
* {@link get_theme_data}, and {@link get_user_data},
* this method returns data after it has been merged
* with the previous origins. This means that if the same piece of data
* is declared in different origins (user, theme, and core),
* the last origin overrides the previous.
*
* For example, if the user has set a background color
* for the paragraph block, and the theme has done it as well,
* the user preference wins.
*
* @param string $origin Optional. To what level should we merge data.
* Valid values are 'theme' or 'custom'.
* Default is 'custom'.
* @return WP_Theme_JSON_Gutenberg
*/
public static function get_merged_data( $origin = 'custom' ) {
$result = parent::get_merged_data( $origin );
_wp_register_webfonts_from_theme_json( $result->get_settings() );

return $result;
}
}
Loading
Loading