PluginProbe
Gutenberg / 13.7.2
Gutenberg v13.7.2
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / experimental / register-webfonts-from-theme-json.php

register-webfonts-from-theme-json.php in Gutenberg 13.7.2, at lib/experimental/register-webfonts-from-theme-json.php

183 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Bootstraps Global Styles.
4 *
5 * @package gutenberg
6 */
7
8 /**
9 * Register webfonts defined in theme.json.
10 */
11 function gutenberg_register_webfonts_from_theme_json() {
12 // Get settings.
13 $settings = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_settings();
14
15 // If in the editor, add webfonts defined in variations.
16 if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
17 $variations = WP_Theme_JSON_Resolver_Gutenberg::get_style_variations();
18
19 foreach ( $variations as $variation ) {
20
21 // Sanity check: Skip if fontFamilies are not defined in the variation.
22 if (
23 empty( $variation['settings'] ) ||
24 empty( $variation['settings']['typography'] ) ||
25 empty( $variation['settings']['typography']['fontFamilies'] )
26 ) {
27 continue;
28 }
29
30 // Merge the variation settings with the global settings.
31 $settings['typography'] = empty( $settings['typography'] ) ? array() : $settings['typography'];
32 $settings['typography']['fontFamilies'] = empty( $settings['typography']['fontFamilies'] ) ? array() : $settings['typography']['fontFamilies'];
33 $settings['typography']['fontFamilies']['theme'] = empty( $settings['typography']['fontFamilies'] ) ? array() : $settings['typography']['fontFamilies']['theme'];
34 $settings['typography']['fontFamilies']['theme'] = array_merge( $settings['typography']['fontFamilies']['theme'], $variation['settings']['typography']['fontFamilies']['theme'] );
35
36 // Make sure there are no duplicates.
37 $settings['typography']['fontFamilies'] = array_unique( $settings['typography']['fontFamilies'] );
38 }
39 }
40
41 // Bail out early if there are no settings for webfonts.
42 if ( empty( $settings['typography'] ) || empty( $settings['typography']['fontFamilies'] ) ) {
43 return;
44 }
45
46 $webfonts = array();
47
48 // Look for fontFamilies.
49 foreach ( $settings['typography']['fontFamilies'] as $font_families ) {
50 foreach ( $font_families as $font_family ) {
51
52 // Skip if fontFace is not defined.
53 if ( empty( $font_family['fontFace'] ) ) {
54 continue;
55 }
56
57 $font_family['fontFace'] = (array) $font_family['fontFace'];
58
59 foreach ( $font_family['fontFace'] as $font_face ) {
60 // Skip if the webfont was registered through the Webfonts API.
61 if ( isset( $font_face['origin'] ) && 'gutenberg_wp_webfonts_api' === $font_face['origin'] ) {
62 continue;
63 }
64
65 // Check if webfonts have a "src" param, and if they do account for the use of "file:./".
66 if ( ! empty( $font_face['src'] ) ) {
67 $font_face['src'] = (array) $font_face['src'];
68
69 foreach ( $font_face['src'] as $src_key => $url ) {
70 // Tweak the URL to be relative to the theme root.
71 if ( ! str_starts_with( $url, 'file:./' ) ) {
72 continue;
73 }
74 $font_face['src'][ $src_key ] = get_theme_file_uri( str_replace( 'file:./', '', $url ) );
75 }
76 }
77
78 // Convert keys to kebab-case.
79 foreach ( $font_face as $property => $value ) {
80 $kebab_case = _wp_to_kebab_case( $property );
81 $font_face[ $kebab_case ] = $value;
82 if ( $kebab_case !== $property ) {
83 unset( $font_face[ $property ] );
84 }
85 }
86
87 $webfonts[] = $font_face;
88 }
89 }
90 }
91 foreach ( $webfonts as $webfont ) {
92 wp_webfonts()->register_webfont( $webfont );
93 }
94 foreach ( $webfonts as $webfont ) {
95 wp_webfonts()->enqueue_webfont( $webfont['font-family'] );
96 }
97 }
98
99 /**
100 * Add missing fonts data to the global styles.
101 *
102 * @param array $data The global styles.
103 * @return array The global styles with missing fonts data.
104 */
105 function gutenberg_add_registered_webfonts_to_theme_json( $data ) {
106 $font_families_registered = wp_webfonts()->get_all_webfonts();
107 $font_families_from_theme = array();
108 if ( ! empty( $data['settings'] ) && ! empty( $data['settings']['typography'] ) && ! empty( $data['settings']['typography']['fontFamilies'] ) ) {
109 $font_families_from_theme = $data['settings']['typography']['fontFamilies'];
110 }
111
112 /**
113 * Helper to get an array of the font-families.
114 *
115 * @param array $families_data The font-families data.
116 * @return array The font-families array.
117 */
118 $get_families = static function( $families_data ) {
119 $families = array();
120 foreach ( $families_data as $family ) {
121 $families[] = WP_Webfonts::get_font_slug( $family );
122 }
123
124 // Micro-optimization: Use array_flip( array_flip( $array ) )
125 // instead of array_unique( $array ) because it's faster.
126 // The result is the same.
127 return array_flip( array_flip( $families ) );
128 };
129
130 // Diff the arrays to find the missing fonts.
131 $to_add = array_diff(
132 array_keys( $font_families_registered ),
133 $get_families( $font_families_from_theme )
134 );
135
136 // Bail out early if there are no missing fonts.
137 if ( empty( $to_add ) ) {
138 return $data;
139 }
140
141 // Make sure the path to settings.typography.fontFamilies.theme exists
142 // before adding missing fonts.
143 if ( empty( $data['settings'] ) ) {
144 $data['settings'] = array();
145 }
146 if ( empty( $data['settings']['typography'] ) ) {
147 $data['settings']['typography'] = array();
148 }
149 if ( empty( $data['settings']['typography']['fontFamilies'] ) ) {
150 $data['settings']['typography']['fontFamilies'] = array();
151 }
152
153 foreach ( $to_add as $slug ) {
154 $font_faces_for_family = $font_families_registered[ $slug ];
155 $family_name = $font_faces_for_family[0]['font-family'];
156 $font_faces = array();
157
158 foreach ( $font_faces_for_family as $font_face ) {
159 $camel_cased = array( 'origin' => 'gutenberg_wp_webfonts_api' );
160 foreach ( $font_face as $key => $value ) {
161 $camel_cased[ lcfirst( str_replace( '-', '', ucwords( $key, '-' ) ) ) ] = $value;
162 }
163 $font_faces[] = $camel_cased;
164 }
165
166 $data['settings']['typography']['fontFamilies'][] = array(
167 'fontFamily' => str_contains( $family_name, ' ' ) ? "'{$family_name}'" : $family_name,
168 'name' => $family_name,
169 'slug' => $slug,
170 'fontFace' => $font_faces,
171 );
172 }
173
174 return $data;
175 }
176
177 // `gutenberg_register_webfonts_from_theme_json()` calls `WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()`, which instantiates `WP_Theme_JSON_Gutenberg()`;
178 // Gutenberg server-side blocks are registered via the init hook with a priority value of `20`. E.g., `add_action( 'init', 'register_block_core_image', 20 )`;
179 // This priority value is added dynamically during the build. See: tools/webpack/blocks.js.
180 // We want to make sure Gutenberg blocks are re-registered before any Theme_JSON operations take place
181 // so that we have access to updated merged data.
182 add_action( 'init', 'gutenberg_register_webfonts_from_theme_json', 21 );
183