changeset 16 | a86126ab1dd4 |
parent 9 | 177826044cd9 |
child 18 | be944660c56a |
15:3d4e9c994f10 | 16:a86126ab1dd4 |
---|---|
13 * linearly with additional themes. Stick to wp_get_theme() if possible. |
13 * linearly with additional themes. Stick to wp_get_theme() if possible. |
14 * |
14 * |
15 * @since 3.4.0 |
15 * @since 3.4.0 |
16 * |
16 * |
17 * @global array $wp_theme_directories |
17 * @global array $wp_theme_directories |
18 * @staticvar array $_themes |
|
19 * |
18 * |
20 * @param array $args { |
19 * @param array $args { |
21 * Optional. The search arguments. |
20 * Optional. The search arguments. |
22 * |
21 * |
23 * @type mixed $errors True to return themes with errors, false to return themes without errors, null to return all themes. |
22 * @type mixed $errors True to return themes with errors, false to return |
24 * Defaults to false. |
23 * themes without errors, null to return all themes. |
25 * @type mixed $allowed (Multisite) True to return only allowed themes for a site. False to return only disallowed themes for a site. |
24 * Default false. |
26 * 'site' to return only site-allowed themes. 'network' to return only network-allowed themes. |
25 * @type mixed $allowed (Multisite) True to return only allowed themes for a site. |
27 * Null to return all themes. Defaults to null. |
26 * False to return only disallowed themes for a site. |
28 * @type int $blog_id (Multisite) The blog ID used to calculate which themes are allowed. |
27 * 'site' to return only site-allowed themes. |
29 * Defaults to 0, synonymous for the current blog. |
28 * 'network' to return only network-allowed themes. |
29 * Null to return all themes. Default null. |
|
30 * @type int $blog_id (Multisite) The blog ID used to calculate which themes |
|
31 * are allowed. Default 0, synonymous for the current blog. |
|
30 * } |
32 * } |
31 * @return WP_Theme[] Array of WP_Theme objects. |
33 * @return WP_Theme[] Array of WP_Theme objects. |
32 */ |
34 */ |
33 function wp_get_themes( $args = array() ) { |
35 function wp_get_themes( $args = array() ) { |
34 global $wp_theme_directories; |
36 global $wp_theme_directories; |
46 // Make sure the current theme wins out, in case search_theme_directories() picks the wrong |
48 // Make sure the current theme wins out, in case search_theme_directories() picks the wrong |
47 // one in the case of a conflict. (Normally, last registered theme root wins.) |
49 // one in the case of a conflict. (Normally, last registered theme root wins.) |
48 $current_theme = get_stylesheet(); |
50 $current_theme = get_stylesheet(); |
49 if ( isset( $theme_directories[ $current_theme ] ) ) { |
51 if ( isset( $theme_directories[ $current_theme ] ) ) { |
50 $root_of_current_theme = get_raw_theme_root( $current_theme ); |
52 $root_of_current_theme = get_raw_theme_root( $current_theme ); |
51 if ( ! in_array( $root_of_current_theme, $wp_theme_directories ) ) { |
53 if ( ! in_array( $root_of_current_theme, $wp_theme_directories, true ) ) { |
52 $root_of_current_theme = WP_CONTENT_DIR . $root_of_current_theme; |
54 $root_of_current_theme = WP_CONTENT_DIR . $root_of_current_theme; |
53 } |
55 } |
54 $theme_directories[ $current_theme ]['theme_root'] = $root_of_current_theme; |
56 $theme_directories[ $current_theme ]['theme_root'] = $root_of_current_theme; |
55 } |
57 } |
56 } |
58 } |
77 |
79 |
78 foreach ( $theme_directories as $theme => $theme_root ) { |
80 foreach ( $theme_directories as $theme => $theme_root ) { |
79 if ( isset( $_themes[ $theme_root['theme_root'] . '/' . $theme ] ) ) { |
81 if ( isset( $_themes[ $theme_root['theme_root'] . '/' . $theme ] ) ) { |
80 $themes[ $theme ] = $_themes[ $theme_root['theme_root'] . '/' . $theme ]; |
82 $themes[ $theme ] = $_themes[ $theme_root['theme_root'] . '/' . $theme ]; |
81 } else { |
83 } else { |
82 $themes[ $theme ] = $_themes[ $theme_root['theme_root'] . '/' . $theme ] = new WP_Theme( $theme, $theme_root['theme_root'] ); |
84 $themes[ $theme ] = new WP_Theme( $theme, $theme_root['theme_root'] ); |
85 |
|
86 $_themes[ $theme_root['theme_root'] . '/' . $theme ] = $themes[ $theme ]; |
|
83 } |
87 } |
84 } |
88 } |
85 |
89 |
86 if ( null !== $args['errors'] ) { |
90 if ( null !== $args['errors'] ) { |
87 foreach ( $themes as $theme => $wp_theme ) { |
91 foreach ( $themes as $theme => $wp_theme ) { |
99 * |
103 * |
100 * @since 3.4.0 |
104 * @since 3.4.0 |
101 * |
105 * |
102 * @global array $wp_theme_directories |
106 * @global array $wp_theme_directories |
103 * |
107 * |
104 * @param string $stylesheet Directory name for the theme. Optional. Defaults to current theme. |
108 * @param string $stylesheet Optional. Directory name for the theme. Defaults to current theme. |
105 * @param string $theme_root Absolute path of the theme root to look in. Optional. If not specified, get_raw_theme_root() |
109 * @param string $theme_root Optional. Absolute path of the theme root to look in. |
106 * is used to calculate the theme root for the $stylesheet provided (or current theme). |
110 * If not specified, get_raw_theme_root() is used to calculate |
107 * @return WP_Theme Theme object. Be sure to check the object's exists() method if you need to confirm the theme's existence. |
111 * the theme root for the $stylesheet provided (or current theme). |
108 */ |
112 * @return WP_Theme Theme object. Be sure to check the object's exists() method |
109 function wp_get_theme( $stylesheet = null, $theme_root = null ) { |
113 * if you need to confirm the theme's existence. |
114 */ |
|
115 function wp_get_theme( $stylesheet = '', $theme_root = '' ) { |
|
110 global $wp_theme_directories; |
116 global $wp_theme_directories; |
111 |
117 |
112 if ( empty( $stylesheet ) ) { |
118 if ( empty( $stylesheet ) ) { |
113 $stylesheet = get_stylesheet(); |
119 $stylesheet = get_stylesheet(); |
114 } |
120 } |
115 |
121 |
116 if ( empty( $theme_root ) ) { |
122 if ( empty( $theme_root ) ) { |
117 $theme_root = get_raw_theme_root( $stylesheet ); |
123 $theme_root = get_raw_theme_root( $stylesheet ); |
118 if ( false === $theme_root ) { |
124 if ( false === $theme_root ) { |
119 $theme_root = WP_CONTENT_DIR . '/themes'; |
125 $theme_root = WP_CONTENT_DIR . '/themes'; |
120 } elseif ( ! in_array( $theme_root, (array) $wp_theme_directories ) ) { |
126 } elseif ( ! in_array( $theme_root, (array) $wp_theme_directories, true ) ) { |
121 $theme_root = WP_CONTENT_DIR . $theme_root; |
127 $theme_root = WP_CONTENT_DIR . $theme_root; |
122 } |
128 } |
123 } |
129 } |
124 |
130 |
125 return new WP_Theme( $stylesheet, $theme_root ); |
131 return new WP_Theme( $stylesheet, $theme_root ); |
127 |
133 |
128 /** |
134 /** |
129 * Clears the cache held by get_theme_roots() and WP_Theme. |
135 * Clears the cache held by get_theme_roots() and WP_Theme. |
130 * |
136 * |
131 * @since 3.5.0 |
137 * @since 3.5.0 |
132 * @param bool $clear_update_cache Whether to clear the Theme updates cache |
138 * @param bool $clear_update_cache Whether to clear the theme updates cache. |
133 */ |
139 */ |
134 function wp_clean_themes_cache( $clear_update_cache = true ) { |
140 function wp_clean_themes_cache( $clear_update_cache = true ) { |
135 if ( $clear_update_cache ) { |
141 if ( $clear_update_cache ) { |
136 delete_site_transient( 'update_themes' ); |
142 delete_site_transient( 'update_themes' ); |
137 } |
143 } |
144 /** |
150 /** |
145 * Whether a child theme is in use. |
151 * Whether a child theme is in use. |
146 * |
152 * |
147 * @since 3.0.0 |
153 * @since 3.0.0 |
148 * |
154 * |
149 * @return bool true if a child theme is in use, false otherwise. |
155 * @return bool True if a child theme is in use, false otherwise. |
150 */ |
156 */ |
151 function is_child_theme() { |
157 function is_child_theme() { |
152 return ( TEMPLATEPATH !== STYLESHEETPATH ); |
158 return ( TEMPLATEPATH !== STYLESHEETPATH ); |
153 } |
159 } |
154 |
160 |
155 /** |
161 /** |
156 * Retrieve name of the current stylesheet. |
162 * Retrieves name of the current stylesheet. |
157 * |
163 * |
158 * The theme name that the administrator has currently set the front end theme |
164 * The theme name that is currently set as the front end theme. |
159 * as. |
165 * |
160 * |
166 * For all intents and purposes, the template name and the stylesheet name |
161 * For all intents and purposes, the template name and the stylesheet name are |
167 * are going to be the same for most cases. |
162 * going to be the same for most cases. |
|
163 * |
168 * |
164 * @since 1.5.0 |
169 * @since 1.5.0 |
165 * |
170 * |
166 * @return string Stylesheet name. |
171 * @return string Stylesheet name. |
167 */ |
172 */ |
175 */ |
180 */ |
176 return apply_filters( 'stylesheet', get_option( 'stylesheet' ) ); |
181 return apply_filters( 'stylesheet', get_option( 'stylesheet' ) ); |
177 } |
182 } |
178 |
183 |
179 /** |
184 /** |
180 * Retrieve stylesheet directory path for current theme. |
185 * Retrieves stylesheet directory path for current theme. |
181 * |
186 * |
182 * @since 1.5.0 |
187 * @since 1.5.0 |
183 * |
188 * |
184 * @return string Path to current theme directory. |
189 * @return string Path to current theme's stylesheet directory. |
185 */ |
190 */ |
186 function get_stylesheet_directory() { |
191 function get_stylesheet_directory() { |
187 $stylesheet = get_stylesheet(); |
192 $stylesheet = get_stylesheet(); |
188 $theme_root = get_theme_root( $stylesheet ); |
193 $theme_root = get_theme_root( $stylesheet ); |
189 $stylesheet_dir = "$theme_root/$stylesheet"; |
194 $stylesheet_dir = "$theme_root/$stylesheet"; |
199 */ |
204 */ |
200 return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); |
205 return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); |
201 } |
206 } |
202 |
207 |
203 /** |
208 /** |
204 * Retrieve stylesheet directory URI. |
209 * Retrieves stylesheet directory URI for current theme. |
205 * |
210 * |
206 * @since 1.5.0 |
211 * @since 1.5.0 |
207 * |
212 * |
208 * @return string |
213 * @return string URI to current theme's stylesheet directory. |
209 */ |
214 */ |
210 function get_stylesheet_directory_uri() { |
215 function get_stylesheet_directory_uri() { |
211 $stylesheet = str_replace( '%2F', '/', rawurlencode( get_stylesheet() ) ); |
216 $stylesheet = str_replace( '%2F', '/', rawurlencode( get_stylesheet() ) ); |
212 $theme_root_uri = get_theme_root_uri( $stylesheet ); |
217 $theme_root_uri = get_theme_root_uri( $stylesheet ); |
213 $stylesheet_dir_uri = "$theme_root_uri/$stylesheet"; |
218 $stylesheet_dir_uri = "$theme_root_uri/$stylesheet"; |
223 */ |
228 */ |
224 return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri ); |
229 return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri ); |
225 } |
230 } |
226 |
231 |
227 /** |
232 /** |
228 * Retrieves the URI of current theme stylesheet. |
233 * Retrieves stylesheet URI for current theme. |
229 * |
234 * |
230 * The stylesheet file name is 'style.css' which is appended to the stylesheet directory URI path. |
235 * The stylesheet file name is 'style.css' which is appended to the stylesheet directory URI path. |
231 * See get_stylesheet_directory_uri(). |
236 * See get_stylesheet_directory_uri(). |
232 * |
237 * |
233 * @since 1.5.0 |
238 * @since 1.5.0 |
234 * |
239 * |
235 * @return string |
240 * @return string URI to current theme's stylesheet. |
236 */ |
241 */ |
237 function get_stylesheet_uri() { |
242 function get_stylesheet_uri() { |
238 $stylesheet_dir_uri = get_stylesheet_directory_uri(); |
243 $stylesheet_dir_uri = get_stylesheet_directory_uri(); |
239 $stylesheet_uri = $stylesheet_dir_uri . '/style.css'; |
244 $stylesheet_uri = $stylesheet_dir_uri . '/style.css'; |
240 /** |
245 /** |
263 * WordPress workflow, then change the former. If you just have the locale in a |
268 * WordPress workflow, then change the former. If you just have the locale in a |
264 * separate folder, then change the latter. |
269 * separate folder, then change the latter. |
265 * |
270 * |
266 * @since 2.1.0 |
271 * @since 2.1.0 |
267 * |
272 * |
268 * @global WP_Locale $wp_locale |
273 * @global WP_Locale $wp_locale WordPress date and time locale object. |
269 * |
274 * |
270 * @return string |
275 * @return string URI to current theme's localized stylesheet. |
271 */ |
276 */ |
272 function get_locale_stylesheet_uri() { |
277 function get_locale_stylesheet_uri() { |
273 global $wp_locale; |
278 global $wp_locale; |
274 $stylesheet_dir_uri = get_stylesheet_directory_uri(); |
279 $stylesheet_dir_uri = get_stylesheet_directory_uri(); |
275 $dir = get_stylesheet_directory(); |
280 $dir = get_stylesheet_directory(); |
291 */ |
296 */ |
292 return apply_filters( 'locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); |
297 return apply_filters( 'locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri ); |
293 } |
298 } |
294 |
299 |
295 /** |
300 /** |
296 * Retrieve name of the current theme. |
301 * Retrieves name of the current theme. |
297 * |
302 * |
298 * @since 1.5.0 |
303 * @since 1.5.0 |
299 * |
304 * |
300 * @return string Template name. |
305 * @return string Template name. |
301 */ |
306 */ |
309 */ |
314 */ |
310 return apply_filters( 'template', get_option( 'template' ) ); |
315 return apply_filters( 'template', get_option( 'template' ) ); |
311 } |
316 } |
312 |
317 |
313 /** |
318 /** |
314 * Retrieve current theme directory. |
319 * Retrieves template directory path for current theme. |
315 * |
320 * |
316 * @since 1.5.0 |
321 * @since 1.5.0 |
317 * |
322 * |
318 * @return string Template directory path. |
323 * @return string Path to current theme's template directory. |
319 */ |
324 */ |
320 function get_template_directory() { |
325 function get_template_directory() { |
321 $template = get_template(); |
326 $template = get_template(); |
322 $theme_root = get_theme_root( $template ); |
327 $theme_root = get_theme_root( $template ); |
323 $template_dir = "$theme_root/$template"; |
328 $template_dir = "$theme_root/$template"; |
325 /** |
330 /** |
326 * Filters the current theme directory path. |
331 * Filters the current theme directory path. |
327 * |
332 * |
328 * @since 1.5.0 |
333 * @since 1.5.0 |
329 * |
334 * |
330 * @param string $template_dir The URI of the current theme directory. |
335 * @param string $template_dir The path of the current theme directory. |
331 * @param string $template Directory name of the current theme. |
336 * @param string $template Directory name of the current theme. |
332 * @param string $theme_root Absolute path to the themes directory. |
337 * @param string $theme_root Absolute path to the themes directory. |
333 */ |
338 */ |
334 return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); |
339 return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); |
335 } |
340 } |
336 |
341 |
337 /** |
342 /** |
338 * Retrieve theme directory URI. |
343 * Retrieves template directory URI for current theme. |
339 * |
344 * |
340 * @since 1.5.0 |
345 * @since 1.5.0 |
341 * |
346 * |
342 * @return string Template directory URI. |
347 * @return string URI to current theme's template directory. |
343 */ |
348 */ |
344 function get_template_directory_uri() { |
349 function get_template_directory_uri() { |
345 $template = str_replace( '%2F', '/', rawurlencode( get_template() ) ); |
350 $template = str_replace( '%2F', '/', rawurlencode( get_template() ) ); |
346 $theme_root_uri = get_theme_root_uri( $template ); |
351 $theme_root_uri = get_theme_root_uri( $template ); |
347 $template_dir_uri = "$theme_root_uri/$template"; |
352 $template_dir_uri = "$theme_root_uri/$template"; |
357 */ |
362 */ |
358 return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); |
363 return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); |
359 } |
364 } |
360 |
365 |
361 /** |
366 /** |
362 * Retrieve theme roots. |
367 * Retrieves theme roots. |
363 * |
368 * |
364 * @since 2.9.0 |
369 * @since 2.9.0 |
365 * |
370 * |
366 * @global array $wp_theme_directories |
371 * @global array $wp_theme_directories |
367 * |
372 * |
368 * @return array|string An array of theme roots keyed by template/stylesheet or a single theme root if all themes have the same root. |
373 * @return array|string An array of theme roots keyed by template/stylesheet |
374 * or a single theme root if all themes have the same root. |
|
369 */ |
375 */ |
370 function get_theme_roots() { |
376 function get_theme_roots() { |
371 global $wp_theme_directories; |
377 global $wp_theme_directories; |
372 |
378 |
373 if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) { |
379 if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) { |
381 } |
387 } |
382 return $theme_roots; |
388 return $theme_roots; |
383 } |
389 } |
384 |
390 |
385 /** |
391 /** |
386 * Register a directory that contains themes. |
392 * Registers a directory that contains themes. |
387 * |
393 * |
388 * @since 2.9.0 |
394 * @since 2.9.0 |
389 * |
395 * |
390 * @global array $wp_theme_directories |
396 * @global array $wp_theme_directories |
391 * |
397 * |
392 * @param string $directory Either the full filesystem path to a theme folder or a folder within WP_CONTENT_DIR |
398 * @param string $directory Either the full filesystem path to a theme folder |
393 * @return bool |
399 * or a folder within WP_CONTENT_DIR. |
400 * @return bool True if successfully registered a directory that contains themes, |
|
401 * false if the directory does not exist. |
|
394 */ |
402 */ |
395 function register_theme_directory( $directory ) { |
403 function register_theme_directory( $directory ) { |
396 global $wp_theme_directories; |
404 global $wp_theme_directories; |
397 |
405 |
398 if ( ! file_exists( $directory ) ) { |
406 if ( ! file_exists( $directory ) ) { |
399 // Try prepending as the theme directory could be relative to the content directory |
407 // Try prepending as the theme directory could be relative to the content directory. |
400 $directory = WP_CONTENT_DIR . '/' . $directory; |
408 $directory = WP_CONTENT_DIR . '/' . $directory; |
401 // If this directory does not exist, return and do not register |
409 // If this directory does not exist, return and do not register. |
402 if ( ! file_exists( $directory ) ) { |
410 if ( ! file_exists( $directory ) ) { |
403 return false; |
411 return false; |
404 } |
412 } |
405 } |
413 } |
406 |
414 |
407 if ( ! is_array( $wp_theme_directories ) ) { |
415 if ( ! is_array( $wp_theme_directories ) ) { |
408 $wp_theme_directories = array(); |
416 $wp_theme_directories = array(); |
409 } |
417 } |
410 |
418 |
411 $untrailed = untrailingslashit( $directory ); |
419 $untrailed = untrailingslashit( $directory ); |
412 if ( ! empty( $untrailed ) && ! in_array( $untrailed, $wp_theme_directories ) ) { |
420 if ( ! empty( $untrailed ) && ! in_array( $untrailed, $wp_theme_directories, true ) ) { |
413 $wp_theme_directories[] = $untrailed; |
421 $wp_theme_directories[] = $untrailed; |
414 } |
422 } |
415 |
423 |
416 return true; |
424 return true; |
417 } |
425 } |
418 |
426 |
419 /** |
427 /** |
420 * Search all registered theme directories for complete and valid themes. |
428 * Searches all registered theme directories for complete and valid themes. |
421 * |
429 * |
422 * @since 2.9.0 |
430 * @since 2.9.0 |
423 * |
431 * |
424 * @global array $wp_theme_directories |
432 * @global array $wp_theme_directories |
425 * @staticvar array $found_themes |
433 * |
426 * |
434 * @param bool $force Optional. Whether to force a new directory scan. Default false. |
427 * @param bool $force Optional. Whether to force a new directory scan. Defaults to false. |
435 * @return array|false Valid themes found on success, false on failure. |
428 * @return array|false Valid themes found |
|
429 */ |
436 */ |
430 function search_theme_directories( $force = false ) { |
437 function search_theme_directories( $force = false ) { |
431 global $wp_theme_directories; |
438 global $wp_theme_directories; |
432 static $found_themes = null; |
439 static $found_themes = null; |
433 |
440 |
442 $found_themes = array(); |
449 $found_themes = array(); |
443 |
450 |
444 $wp_theme_directories = (array) $wp_theme_directories; |
451 $wp_theme_directories = (array) $wp_theme_directories; |
445 $relative_theme_roots = array(); |
452 $relative_theme_roots = array(); |
446 |
453 |
447 // Set up maybe-relative, maybe-absolute array of theme directories. |
454 /* |
448 // We always want to return absolute, but we need to cache relative |
455 * Set up maybe-relative, maybe-absolute array of theme directories. |
449 // to use in get_theme_root(). |
456 * We always want to return absolute, but we need to cache relative |
457 * to use in get_theme_root(). |
|
458 */ |
|
450 foreach ( $wp_theme_directories as $theme_root ) { |
459 foreach ( $wp_theme_directories as $theme_root ) { |
451 if ( 0 === strpos( $theme_root, WP_CONTENT_DIR ) ) { |
460 if ( 0 === strpos( $theme_root, WP_CONTENT_DIR ) ) { |
452 $relative_theme_roots[ str_replace( WP_CONTENT_DIR, '', $theme_root ) ] = $theme_root; |
461 $relative_theme_roots[ str_replace( WP_CONTENT_DIR, '', $theme_root ) ] = $theme_root; |
453 } else { |
462 } else { |
454 $relative_theme_roots[ $theme_root ] = $theme_root; |
463 $relative_theme_roots[ $theme_root ] = $theme_root; |
459 * Filters whether to get the cache of the registered theme directories. |
468 * Filters whether to get the cache of the registered theme directories. |
460 * |
469 * |
461 * @since 3.4.0 |
470 * @since 3.4.0 |
462 * |
471 * |
463 * @param bool $cache_expiration Whether to get the cache of the theme directories. Default false. |
472 * @param bool $cache_expiration Whether to get the cache of the theme directories. Default false. |
464 * @param string $cache_directory Directory to be searched for the cache. |
473 * @param string $context The class or function name calling the filter. |
465 */ |
474 */ |
466 if ( $cache_expiration = apply_filters( 'wp_cache_themes_persistently', false, 'search_theme_directories' ) ) { |
475 $cache_expiration = apply_filters( 'wp_cache_themes_persistently', false, 'search_theme_directories' ); |
476 |
|
477 if ( $cache_expiration ) { |
|
467 $cached_roots = get_site_transient( 'theme_roots' ); |
478 $cached_roots = get_site_transient( 'theme_roots' ); |
468 if ( is_array( $cached_roots ) ) { |
479 if ( is_array( $cached_roots ) ) { |
469 foreach ( $cached_roots as $theme_dir => $theme_root ) { |
480 foreach ( $cached_roots as $theme_dir => $theme_root ) { |
470 // A cached theme root is no longer around, so skip it. |
481 // A cached theme root is no longer around, so skip it. |
471 if ( ! isset( $relative_theme_roots[ $theme_root ] ) ) { |
482 if ( ! isset( $relative_theme_roots[ $theme_root ] ) ) { |
477 ); |
488 ); |
478 } |
489 } |
479 return $found_themes; |
490 return $found_themes; |
480 } |
491 } |
481 if ( ! is_int( $cache_expiration ) ) { |
492 if ( ! is_int( $cache_expiration ) ) { |
482 $cache_expiration = 1800; // half hour |
493 $cache_expiration = 30 * MINUTE_IN_SECONDS; |
483 } |
494 } |
484 } else { |
495 } else { |
485 $cache_expiration = 1800; // half hour |
496 $cache_expiration = 30 * MINUTE_IN_SECONDS; |
486 } |
497 } |
487 |
498 |
488 /* Loop the registered theme directories and extract all themes */ |
499 /* Loop the registered theme directories and extract all themes */ |
489 foreach ( $wp_theme_directories as $theme_root ) { |
500 foreach ( $wp_theme_directories as $theme_root ) { |
490 |
501 |
493 if ( ! $dirs ) { |
504 if ( ! $dirs ) { |
494 trigger_error( "$theme_root is not readable", E_USER_NOTICE ); |
505 trigger_error( "$theme_root is not readable", E_USER_NOTICE ); |
495 continue; |
506 continue; |
496 } |
507 } |
497 foreach ( $dirs as $dir ) { |
508 foreach ( $dirs as $dir ) { |
498 if ( ! is_dir( $theme_root . '/' . $dir ) || $dir[0] == '.' || $dir == 'CVS' ) { |
509 if ( ! is_dir( $theme_root . '/' . $dir ) || '.' === $dir[0] || 'CVS' === $dir ) { |
499 continue; |
510 continue; |
500 } |
511 } |
501 if ( file_exists( $theme_root . '/' . $dir . '/style.css' ) ) { |
512 if ( file_exists( $theme_root . '/' . $dir . '/style.css' ) ) { |
502 // wp-content/themes/a-single-theme |
513 // wp-content/themes/a-single-theme |
503 // wp-content/themes is $theme_root, a-single-theme is $dir |
514 // wp-content/themes is $theme_root, a-single-theme is $dir. |
504 $found_themes[ $dir ] = array( |
515 $found_themes[ $dir ] = array( |
505 'theme_file' => $dir . '/style.css', |
516 'theme_file' => $dir . '/style.css', |
506 'theme_root' => $theme_root, |
517 'theme_root' => $theme_root, |
507 ); |
518 ); |
508 } else { |
519 } else { |
509 $found_theme = false; |
520 $found_theme = false; |
510 // wp-content/themes/a-folder-of-themes/* |
521 // wp-content/themes/a-folder-of-themes/* |
511 // wp-content/themes is $theme_root, a-folder-of-themes is $dir, then themes are $sub_dirs |
522 // wp-content/themes is $theme_root, a-folder-of-themes is $dir, then themes are $sub_dirs. |
512 $sub_dirs = @ scandir( $theme_root . '/' . $dir ); |
523 $sub_dirs = @ scandir( $theme_root . '/' . $dir ); |
513 if ( ! $sub_dirs ) { |
524 if ( ! $sub_dirs ) { |
514 trigger_error( "$theme_root/$dir is not readable", E_USER_NOTICE ); |
525 trigger_error( "$theme_root/$dir is not readable", E_USER_NOTICE ); |
515 continue; |
526 continue; |
516 } |
527 } |
517 foreach ( $sub_dirs as $sub_dir ) { |
528 foreach ( $sub_dirs as $sub_dir ) { |
518 if ( ! is_dir( $theme_root . '/' . $dir . '/' . $sub_dir ) || $dir[0] == '.' || $dir == 'CVS' ) { |
529 if ( ! is_dir( $theme_root . '/' . $dir . '/' . $sub_dir ) || '.' === $dir[0] || 'CVS' === $dir ) { |
519 continue; |
530 continue; |
520 } |
531 } |
521 if ( ! file_exists( $theme_root . '/' . $dir . '/' . $sub_dir . '/style.css' ) ) { |
532 if ( ! file_exists( $theme_root . '/' . $dir . '/' . $sub_dir . '/style.css' ) ) { |
522 continue; |
533 continue; |
523 } |
534 } |
546 |
557 |
547 foreach ( $found_themes as $theme_dir => $theme_data ) { |
558 foreach ( $found_themes as $theme_dir => $theme_data ) { |
548 $theme_roots[ $theme_dir ] = $relative_theme_roots[ $theme_data['theme_root'] ]; // Convert absolute to relative. |
559 $theme_roots[ $theme_dir ] = $relative_theme_roots[ $theme_data['theme_root'] ]; // Convert absolute to relative. |
549 } |
560 } |
550 |
561 |
551 if ( $theme_roots != get_site_transient( 'theme_roots' ) ) { |
562 if ( get_site_transient( 'theme_roots' ) != $theme_roots ) { |
552 set_site_transient( 'theme_roots', $theme_roots, $cache_expiration ); |
563 set_site_transient( 'theme_roots', $theme_roots, $cache_expiration ); |
553 } |
564 } |
554 |
565 |
555 return $found_themes; |
566 return $found_themes; |
556 } |
567 } |
557 |
568 |
558 /** |
569 /** |
559 * Retrieve path to themes directory. |
570 * Retrieves path to themes directory. |
560 * |
571 * |
561 * Does not have trailing slash. |
572 * Does not have trailing slash. |
562 * |
573 * |
563 * @since 1.5.0 |
574 * @since 1.5.0 |
564 * |
575 * |
565 * @global array $wp_theme_directories |
576 * @global array $wp_theme_directories |
566 * |
577 * |
567 * @param string $stylesheet_or_template The stylesheet or template name of the theme |
578 * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. |
568 * @return string Theme path. |
579 * Default is to leverage the main theme root. |
569 */ |
580 * @return string Themes directory path. |
570 function get_theme_root( $stylesheet_or_template = false ) { |
581 */ |
582 function get_theme_root( $stylesheet_or_template = '' ) { |
|
571 global $wp_theme_directories; |
583 global $wp_theme_directories; |
572 |
584 |
573 if ( $stylesheet_or_template && $theme_root = get_raw_theme_root( $stylesheet_or_template ) ) { |
585 $theme_root = ''; |
574 // Always prepend WP_CONTENT_DIR unless the root currently registered as a theme directory. |
586 |
575 // This gives relative theme roots the benefit of the doubt when things go haywire. |
587 if ( $stylesheet_or_template ) { |
576 if ( ! in_array( $theme_root, (array) $wp_theme_directories ) ) { |
588 $theme_root = get_raw_theme_root( $stylesheet_or_template ); |
577 $theme_root = WP_CONTENT_DIR . $theme_root; |
589 if ( $theme_root ) { |
578 } |
590 // Always prepend WP_CONTENT_DIR unless the root currently registered as a theme directory. |
579 } else { |
591 // This gives relative theme roots the benefit of the doubt when things go haywire. |
592 if ( ! in_array( $theme_root, (array) $wp_theme_directories, true ) ) { |
|
593 $theme_root = WP_CONTENT_DIR . $theme_root; |
|
594 } |
|
595 } |
|
596 } |
|
597 |
|
598 if ( ! $theme_root ) { |
|
580 $theme_root = WP_CONTENT_DIR . '/themes'; |
599 $theme_root = WP_CONTENT_DIR . '/themes'; |
581 } |
600 } |
582 |
601 |
583 /** |
602 /** |
584 * Filters the absolute path to the themes directory. |
603 * Filters the absolute path to the themes directory. |
589 */ |
608 */ |
590 return apply_filters( 'theme_root', $theme_root ); |
609 return apply_filters( 'theme_root', $theme_root ); |
591 } |
610 } |
592 |
611 |
593 /** |
612 /** |
594 * Retrieve URI for themes directory. |
613 * Retrieves URI for themes directory. |
595 * |
614 * |
596 * Does not have trailing slash. |
615 * Does not have trailing slash. |
597 * |
616 * |
598 * @since 1.5.0 |
617 * @since 1.5.0 |
599 * |
618 * |
600 * @global array $wp_theme_directories |
619 * @global array $wp_theme_directories |
601 * |
620 * |
602 * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. |
621 * @param string $stylesheet_or_template Optional. The stylesheet or template name of the theme. |
603 * Default is to leverage the main theme root. |
622 * Default is to leverage the main theme root. |
604 * @param string $theme_root Optional. The theme root for which calculations will be based, preventing |
623 * @param string $theme_root Optional. The theme root for which calculations will be based, |
605 * the need for a get_raw_theme_root() call. |
624 * preventing the need for a get_raw_theme_root() call. Default empty. |
606 * @return string Themes URI. |
625 * @return string Themes directory URI. |
607 */ |
626 */ |
608 function get_theme_root_uri( $stylesheet_or_template = false, $theme_root = false ) { |
627 function get_theme_root_uri( $stylesheet_or_template = '', $theme_root = '' ) { |
609 global $wp_theme_directories; |
628 global $wp_theme_directories; |
610 |
629 |
611 if ( $stylesheet_or_template && ! $theme_root ) { |
630 if ( $stylesheet_or_template && ! $theme_root ) { |
612 $theme_root = get_raw_theme_root( $stylesheet_or_template ); |
631 $theme_root = get_raw_theme_root( $stylesheet_or_template ); |
613 } |
632 } |
614 |
633 |
615 if ( $stylesheet_or_template && $theme_root ) { |
634 if ( $stylesheet_or_template && $theme_root ) { |
616 if ( in_array( $theme_root, (array) $wp_theme_directories ) ) { |
635 if ( in_array( $theme_root, (array) $wp_theme_directories, true ) ) { |
617 // Absolute path. Make an educated guess. YMMV -- but note the filter below. |
636 // Absolute path. Make an educated guess. YMMV -- but note the filter below. |
618 if ( 0 === strpos( $theme_root, WP_CONTENT_DIR ) ) { |
637 if ( 0 === strpos( $theme_root, WP_CONTENT_DIR ) ) { |
619 $theme_root_uri = content_url( str_replace( WP_CONTENT_DIR, '', $theme_root ) ); |
638 $theme_root_uri = content_url( str_replace( WP_CONTENT_DIR, '', $theme_root ) ); |
620 } elseif ( 0 === strpos( $theme_root, ABSPATH ) ) { |
639 } elseif ( 0 === strpos( $theme_root, ABSPATH ) ) { |
621 $theme_root_uri = site_url( str_replace( ABSPATH, '', $theme_root ) ); |
640 $theme_root_uri = site_url( str_replace( ABSPATH, '', $theme_root ) ); |
636 * |
655 * |
637 * @since 1.5.0 |
656 * @since 1.5.0 |
638 * |
657 * |
639 * @param string $theme_root_uri The URI for themes directory. |
658 * @param string $theme_root_uri The URI for themes directory. |
640 * @param string $siteurl WordPress web address which is set in General Options. |
659 * @param string $siteurl WordPress web address which is set in General Options. |
641 * @param string $stylesheet_or_template Stylesheet or template name of the theme. |
660 * @param string $stylesheet_or_template The stylesheet or template name of the theme. |
642 */ |
661 */ |
643 return apply_filters( 'theme_root_uri', $theme_root_uri, get_option( 'siteurl' ), $stylesheet_or_template ); |
662 return apply_filters( 'theme_root_uri', $theme_root_uri, get_option( 'siteurl' ), $stylesheet_or_template ); |
644 } |
663 } |
645 |
664 |
646 /** |
665 /** |
647 * Get the raw theme root relative to the content directory with no filters applied. |
666 * Gets the raw theme root relative to the content directory with no filters applied. |
648 * |
667 * |
649 * @since 3.1.0 |
668 * @since 3.1.0 |
650 * |
669 * |
651 * @global array $wp_theme_directories |
670 * @global array $wp_theme_directories |
652 * |
671 * |
653 * @param string $stylesheet_or_template The stylesheet or template name of the theme |
672 * @param string $stylesheet_or_template The stylesheet or template name of the theme. |
654 * @param bool $skip_cache Optional. Whether to skip the cache. |
673 * @param bool $skip_cache Optional. Whether to skip the cache. |
655 * Defaults to false, meaning the cache is used. |
674 * Defaults to false, meaning the cache is used. |
656 * @return string Theme root |
675 * @return string Theme root. |
657 */ |
676 */ |
658 function get_raw_theme_root( $stylesheet_or_template, $skip_cache = false ) { |
677 function get_raw_theme_root( $stylesheet_or_template, $skip_cache = false ) { |
659 global $wp_theme_directories; |
678 global $wp_theme_directories; |
660 |
679 |
661 if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) { |
680 if ( ! is_array( $wp_theme_directories ) || count( $wp_theme_directories ) <= 1 ) { |
662 return '/themes'; |
681 return '/themes'; |
663 } |
682 } |
664 |
683 |
665 $theme_root = false; |
684 $theme_root = false; |
666 |
685 |
667 // If requesting the root for the current theme, consult options to avoid calling get_theme_roots() |
686 // If requesting the root for the current theme, consult options to avoid calling get_theme_roots(). |
668 if ( ! $skip_cache ) { |
687 if ( ! $skip_cache ) { |
669 if ( get_option( 'stylesheet' ) == $stylesheet_or_template ) { |
688 if ( get_option( 'stylesheet' ) == $stylesheet_or_template ) { |
670 $theme_root = get_option( 'stylesheet_root' ); |
689 $theme_root = get_option( 'stylesheet_root' ); |
671 } elseif ( get_option( 'template' ) == $stylesheet_or_template ) { |
690 } elseif ( get_option( 'template' ) == $stylesheet_or_template ) { |
672 $theme_root = get_option( 'template_root' ); |
691 $theme_root = get_option( 'template_root' ); |
682 |
701 |
683 return $theme_root; |
702 return $theme_root; |
684 } |
703 } |
685 |
704 |
686 /** |
705 /** |
687 * Display localized stylesheet link element. |
706 * Displays localized stylesheet link element. |
688 * |
707 * |
689 * @since 2.1.0 |
708 * @since 2.1.0 |
690 */ |
709 */ |
691 function locale_stylesheet() { |
710 function locale_stylesheet() { |
692 $stylesheet = get_locale_stylesheet_uri(); |
711 $stylesheet = get_locale_stylesheet_uri(); |
693 if ( empty( $stylesheet ) ) { |
712 if ( empty( $stylesheet ) ) { |
694 return; |
713 return; |
695 } |
714 } |
696 echo '<link rel="stylesheet" href="' . $stylesheet . '" type="text/css" media="screen" />'; |
715 |
716 $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; |
|
717 |
|
718 printf( |
|
719 '<link rel="stylesheet" href="%s"%s media="screen" />', |
|
720 $stylesheet, |
|
721 $type_attr |
|
722 ); |
|
697 } |
723 } |
698 |
724 |
699 /** |
725 /** |
700 * Switches the theme. |
726 * Switches the theme. |
701 * |
727 * |
706 * |
732 * |
707 * @global array $wp_theme_directories |
733 * @global array $wp_theme_directories |
708 * @global WP_Customize_Manager $wp_customize |
734 * @global WP_Customize_Manager $wp_customize |
709 * @global array $sidebars_widgets |
735 * @global array $sidebars_widgets |
710 * |
736 * |
711 * @param string $stylesheet Stylesheet name |
737 * @param string $stylesheet Stylesheet name. |
712 */ |
738 */ |
713 function switch_theme( $stylesheet ) { |
739 function switch_theme( $stylesheet ) { |
714 global $wp_theme_directories, $wp_customize, $sidebars_widgets; |
740 global $wp_theme_directories, $wp_customize, $sidebars_widgets; |
741 |
|
742 $requirements = validate_theme_requirements( $stylesheet ); |
|
743 if ( is_wp_error( $requirements ) ) { |
|
744 wp_die( $requirements ); |
|
745 } |
|
715 |
746 |
716 $_sidebars_widgets = null; |
747 $_sidebars_widgets = null; |
717 if ( 'wp_ajax_customize_save' === current_action() ) { |
748 if ( 'wp_ajax_customize_save' === current_action() ) { |
718 $old_sidebars_widgets_data_setting = $wp_customize->get_setting( 'old_sidebars_widgets_data' ); |
749 $old_sidebars_widgets_data_setting = $wp_customize->get_setting( 'old_sidebars_widgets_data' ); |
719 if ( $old_sidebars_widgets_data_setting ) { |
750 if ( $old_sidebars_widgets_data_setting ) { |
797 */ |
828 */ |
798 do_action( 'switch_theme', $new_name, $new_theme, $old_theme ); |
829 do_action( 'switch_theme', $new_name, $new_theme, $old_theme ); |
799 } |
830 } |
800 |
831 |
801 /** |
832 /** |
802 * Checks that current theme files 'index.php' and 'style.css' exists. |
833 * Checks that the current theme has 'index.php' and 'style.css' files. |
803 * |
834 * |
804 * Does not initially check the default theme, which is the fallback and should always exist. |
835 * Does not initially check the default theme, which is the fallback and should always exist. |
805 * But if it doesn't exist, it'll fall back to the latest core default theme that does exist. |
836 * But if it doesn't exist, it'll fall back to the latest core default theme that does exist. |
806 * Will switch theme to the fallback theme if current theme does not validate. |
837 * Will switch theme to the fallback theme if current theme does not validate. |
807 * |
838 * |
808 * You can use the {@see 'validate_current_theme'} filter to return false to |
839 * You can use the {@see 'validate_current_theme'} filter to return false to disable |
809 * disable this functionality. |
840 * this functionality. |
810 * |
841 * |
811 * @since 1.5.0 |
842 * @since 1.5.0 |
843 * |
|
812 * @see WP_DEFAULT_THEME |
844 * @see WP_DEFAULT_THEME |
813 * |
845 * |
814 * @return bool |
846 * @return bool |
815 */ |
847 */ |
816 function validate_current_theme() { |
848 function validate_current_theme() { |
843 } |
875 } |
844 |
876 |
845 /** |
877 /** |
846 * If we're in an invalid state but WP_DEFAULT_THEME doesn't exist, |
878 * If we're in an invalid state but WP_DEFAULT_THEME doesn't exist, |
847 * switch to the latest core default theme that's installed. |
879 * switch to the latest core default theme that's installed. |
880 * |
|
848 * If it turns out that this latest core default theme is our current |
881 * If it turns out that this latest core default theme is our current |
849 * theme, then there's nothing we can do about that, so we have to bail, |
882 * theme, then there's nothing we can do about that, so we have to bail, |
850 * rather than going into an infinite loop. (This is why there are |
883 * rather than going into an infinite loop. (This is why there are |
851 * checks against WP_DEFAULT_THEME above, also.) We also can't do anything |
884 * checks against WP_DEFAULT_THEME above, also.) We also can't do anything |
852 * if it turns out there is no default theme installed. (That's `false`.) |
885 * if it turns out there is no default theme installed. (That's `false`.) |
859 switch_theme( $default->get_stylesheet() ); |
892 switch_theme( $default->get_stylesheet() ); |
860 return false; |
893 return false; |
861 } |
894 } |
862 |
895 |
863 /** |
896 /** |
864 * Retrieve all theme modifications. |
897 * Validates the theme requirements for WordPress version and PHP version. |
898 * |
|
899 * Uses the information from `Requires at least` and `Requires PHP` headers |
|
900 * defined in the theme's `style.css` file. |
|
901 * |
|
902 * If the headers are not present in the theme's stylesheet file, |
|
903 * `readme.txt` is also checked as a fallback. |
|
904 * |
|
905 * @since 5.5.0 |
|
906 * |
|
907 * @param string $stylesheet Directory name for the theme. |
|
908 * @return true|WP_Error True if requirements are met, WP_Error on failure. |
|
909 */ |
|
910 function validate_theme_requirements( $stylesheet ) { |
|
911 $theme = wp_get_theme( $stylesheet ); |
|
912 |
|
913 $requirements = array( |
|
914 'requires' => ! empty( $theme->get( 'RequiresWP' ) ) ? $theme->get( 'RequiresWP' ) : '', |
|
915 'requires_php' => ! empty( $theme->get( 'RequiresPHP' ) ) ? $theme->get( 'RequiresPHP' ) : '', |
|
916 ); |
|
917 |
|
918 $readme_file = $theme->theme_root . '/' . $stylesheet . '/readme.txt'; |
|
919 |
|
920 if ( file_exists( $readme_file ) ) { |
|
921 $readme_headers = get_file_data( |
|
922 $readme_file, |
|
923 array( |
|
924 'requires' => 'Requires at least', |
|
925 'requires_php' => 'Requires PHP', |
|
926 ), |
|
927 'theme' |
|
928 ); |
|
929 |
|
930 $requirements = array_merge( $readme_headers, $requirements ); |
|
931 } |
|
932 |
|
933 $compatible_wp = is_wp_version_compatible( $requirements['requires'] ); |
|
934 $compatible_php = is_php_version_compatible( $requirements['requires_php'] ); |
|
935 |
|
936 if ( ! $compatible_wp && ! $compatible_php ) { |
|
937 return new WP_Error( |
|
938 'theme_wp_php_incompatible', |
|
939 sprintf( |
|
940 /* translators: %s: Theme name. */ |
|
941 _x( '<strong>Error:</strong> Current WordPress and PHP versions do not meet minimum requirements for %s.', 'theme' ), |
|
942 $theme->display( 'Name' ) |
|
943 ) |
|
944 ); |
|
945 } elseif ( ! $compatible_php ) { |
|
946 return new WP_Error( |
|
947 'theme_php_incompatible', |
|
948 sprintf( |
|
949 /* translators: %s: Theme name. */ |
|
950 _x( '<strong>Error:</strong> Current PHP version does not meet minimum requirements for %s.', 'theme' ), |
|
951 $theme->display( 'Name' ) |
|
952 ) |
|
953 ); |
|
954 } elseif ( ! $compatible_wp ) { |
|
955 return new WP_Error( |
|
956 'theme_wp_incompatible', |
|
957 sprintf( |
|
958 /* translators: %s: Theme name. */ |
|
959 _x( '<strong>Error:</strong> Current WordPress version does not meet minimum requirements for %s.', 'theme' ), |
|
960 $theme->display( 'Name' ) |
|
961 ) |
|
962 ); |
|
963 } |
|
964 |
|
965 return true; |
|
966 } |
|
967 |
|
968 /** |
|
969 * Retrieves all theme modifications. |
|
865 * |
970 * |
866 * @since 3.1.0 |
971 * @since 3.1.0 |
867 * |
972 * |
868 * @return array|void Theme modifications. |
973 * @return array|void Theme modifications. |
869 */ |
974 */ |
883 } |
988 } |
884 return $mods; |
989 return $mods; |
885 } |
990 } |
886 |
991 |
887 /** |
992 /** |
888 * Retrieve theme modification value for the current theme. |
993 * Retrieves theme modification value for the current theme. |
889 * |
994 * |
890 * If the modification name does not exist, then the $default will be passed |
995 * If the modification name does not exist, then the $default will be passed |
891 * through {@link https://secure.php.net/sprintf sprintf()} PHP function with the first |
996 * through {@link https://www.php.net/sprintf sprintf()} PHP function with |
892 * string the template directory URI and the second string the stylesheet |
997 * the template directory URI as the first string and the stylesheet directory URI |
893 * directory URI. |
998 * as the second string. |
894 * |
999 * |
895 * @since 2.1.0 |
1000 * @since 2.1.0 |
896 * |
1001 * |
897 * @param string $name Theme modification name. |
1002 * @param string $name Theme modification name. |
898 * @param bool|string $default |
1003 * @param string|false $default Optional. Theme modification default value. Default false. |
899 * @return mixed |
1004 * @return mixed Theme modification value. |
900 */ |
1005 */ |
901 function get_theme_mod( $name, $default = false ) { |
1006 function get_theme_mod( $name, $default = false ) { |
902 $mods = get_theme_mods(); |
1007 $mods = get_theme_mods(); |
903 |
1008 |
904 if ( isset( $mods[ $name ] ) ) { |
1009 if ( isset( $mods[ $name ] ) ) { |
905 /** |
1010 /** |
906 * Filters the theme modification, or 'theme_mod', value. |
1011 * Filters the theme modification, or 'theme_mod', value. |
907 * |
1012 * |
908 * The dynamic portion of the hook name, `$name`, refers to |
1013 * The dynamic portion of the hook name, `$name`, refers to the key name |
909 * the key name of the modification array. For example, |
1014 * of the modification array. For example, 'header_textcolor', 'header_image', |
910 * 'header_textcolor', 'header_image', and so on depending |
1015 * and so on depending on the theme options. |
911 * on the theme options. |
|
912 * |
1016 * |
913 * @since 2.2.0 |
1017 * @since 2.2.0 |
914 * |
1018 * |
915 * @param string $current_mod The value of the current theme modification. |
1019 * @param string $current_mod The value of the current theme modification. |
916 */ |
1020 */ |
917 return apply_filters( "theme_mod_{$name}", $mods[ $name ] ); |
1021 return apply_filters( "theme_mod_{$name}", $mods[ $name ] ); |
918 } |
1022 } |
919 |
1023 |
920 if ( is_string( $default ) ) { |
1024 if ( is_string( $default ) ) { |
921 $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1025 // Only run the replacement if an sprintf() string format pattern was found. |
1026 if ( preg_match( '#(?<!%)%(?:\d+\$?)?s#', $default ) ) { |
|
1027 $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
|
1028 } |
|
922 } |
1029 } |
923 |
1030 |
924 /** This filter is documented in wp-includes/theme.php */ |
1031 /** This filter is documented in wp-includes/theme.php */ |
925 return apply_filters( "theme_mod_{$name}", $default ); |
1032 return apply_filters( "theme_mod_{$name}", $default ); |
926 } |
1033 } |
927 |
1034 |
928 /** |
1035 /** |
929 * Update theme modification value for the current theme. |
1036 * Updates theme modification value for the current theme. |
930 * |
1037 * |
931 * @since 2.1.0 |
1038 * @since 2.1.0 |
932 * |
1039 * |
933 * @param string $name Theme modification name. |
1040 * @param string $name Theme modification name. |
934 * @param mixed $value Theme modification value. |
1041 * @param mixed $value Theme modification value. |
936 function set_theme_mod( $name, $value ) { |
1043 function set_theme_mod( $name, $value ) { |
937 $mods = get_theme_mods(); |
1044 $mods = get_theme_mods(); |
938 $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; |
1045 $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; |
939 |
1046 |
940 /** |
1047 /** |
941 * Filters the theme mod value on save. |
1048 * Filters the theme modification, or 'theme_mod', value on save. |
942 * |
1049 * |
943 * The dynamic portion of the hook name, `$name`, refers to the key name of |
1050 * The dynamic portion of the hook name, `$name`, refers to the key name |
944 * the modification array. For example, 'header_textcolor', 'header_image', |
1051 * of the modification array. For example, 'header_textcolor', 'header_image', |
945 * and so on depending on the theme options. |
1052 * and so on depending on the theme options. |
946 * |
1053 * |
947 * @since 3.9.0 |
1054 * @since 3.9.0 |
948 * |
1055 * |
949 * @param string $value The new value of the theme mod. |
1056 * @param string $value The new value of the theme modification. |
950 * @param string $old_value The current value of the theme mod. |
1057 * @param string $old_value The current value of the theme modification. |
951 */ |
1058 */ |
952 $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); |
1059 $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); |
953 |
1060 |
954 $theme = get_option( 'stylesheet' ); |
1061 $theme = get_option( 'stylesheet' ); |
955 update_option( "theme_mods_$theme", $mods ); |
1062 update_option( "theme_mods_$theme", $mods ); |
956 } |
1063 } |
957 |
1064 |
958 /** |
1065 /** |
959 * Remove theme modification name from current theme list. |
1066 * Removes theme modification name from current theme list. |
960 * |
1067 * |
961 * If removing the name also removes all elements, then the entire option will |
1068 * If removing the name also removes all elements, then the entire option |
962 * be removed. |
1069 * will be removed. |
963 * |
1070 * |
964 * @since 2.1.0 |
1071 * @since 2.1.0 |
965 * |
1072 * |
966 * @param string $name Theme modification name. |
1073 * @param string $name Theme modification name. |
967 */ |
1074 */ |
981 $theme = get_option( 'stylesheet' ); |
1088 $theme = get_option( 'stylesheet' ); |
982 update_option( "theme_mods_$theme", $mods ); |
1089 update_option( "theme_mods_$theme", $mods ); |
983 } |
1090 } |
984 |
1091 |
985 /** |
1092 /** |
986 * Remove theme modifications option for current theme. |
1093 * Removes theme modifications option for current theme. |
987 * |
1094 * |
988 * @since 2.1.0 |
1095 * @since 2.1.0 |
989 */ |
1096 */ |
990 function remove_theme_mods() { |
1097 function remove_theme_mods() { |
991 delete_option( 'theme_mods_' . get_option( 'stylesheet' ) ); |
1098 delete_option( 'theme_mods_' . get_option( 'stylesheet' ) ); |
1033 $text_color = get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); |
1140 $text_color = get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) ); |
1034 return 'blank' !== $text_color; |
1141 return 'blank' !== $text_color; |
1035 } |
1142 } |
1036 |
1143 |
1037 /** |
1144 /** |
1038 * Check whether a header image is set or not. |
1145 * Checks whether a header image is set or not. |
1039 * |
1146 * |
1040 * @since 4.2.0 |
1147 * @since 4.2.0 |
1041 * |
1148 * |
1042 * @see get_header_image() |
1149 * @see get_header_image() |
1043 * |
1150 * |
1046 function has_header_image() { |
1153 function has_header_image() { |
1047 return (bool) get_header_image(); |
1154 return (bool) get_header_image(); |
1048 } |
1155 } |
1049 |
1156 |
1050 /** |
1157 /** |
1051 * Retrieve header image for custom header. |
1158 * Retrieves header image for custom header. |
1052 * |
1159 * |
1053 * @since 2.1.0 |
1160 * @since 2.1.0 |
1054 * |
1161 * |
1055 * @return string|false |
1162 * @return string|false |
1056 */ |
1163 */ |
1057 function get_header_image() { |
1164 function get_header_image() { |
1058 $url = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) ); |
1165 $url = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) ); |
1059 |
1166 |
1060 if ( 'remove-header' == $url ) { |
1167 if ( 'remove-header' === $url ) { |
1061 return false; |
1168 return false; |
1062 } |
1169 } |
1063 |
1170 |
1064 if ( is_random_header_image() ) { |
1171 if ( is_random_header_image() ) { |
1065 $url = get_random_header_image(); |
1172 $url = get_random_header_image(); |
1067 |
1174 |
1068 return esc_url_raw( set_url_scheme( $url ) ); |
1175 return esc_url_raw( set_url_scheme( $url ) ); |
1069 } |
1176 } |
1070 |
1177 |
1071 /** |
1178 /** |
1072 * Create image tag markup for a custom header image. |
1179 * Creates image tag markup for a custom header image. |
1073 * |
1180 * |
1074 * @since 4.4.0 |
1181 * @since 4.4.0 |
1075 * |
1182 * |
1076 * @param array $attr Optional. Additional attributes for the image tag. Can be used |
1183 * @param array $attr Optional. Additional attributes for the image tag. Can be used |
1077 * to override the default attributes. Default empty. |
1184 * to override the default attributes. Default empty. |
1134 */ |
1241 */ |
1135 return apply_filters( 'get_header_image_tag', $html, $header, $attr ); |
1242 return apply_filters( 'get_header_image_tag', $html, $header, $attr ); |
1136 } |
1243 } |
1137 |
1244 |
1138 /** |
1245 /** |
1139 * Display the image markup for a custom header image. |
1246 * Displays the image markup for a custom header image. |
1140 * |
1247 * |
1141 * @since 4.4.0 |
1248 * @since 4.4.0 |
1142 * |
1249 * |
1143 * @param array $attr Optional. Attributes for the image markup. Default empty. |
1250 * @param array $attr Optional. Attributes for the image markup. Default empty. |
1144 */ |
1251 */ |
1145 function the_header_image_tag( $attr = array() ) { |
1252 function the_header_image_tag( $attr = array() ) { |
1146 echo get_header_image_tag( $attr ); |
1253 echo get_header_image_tag( $attr ); |
1147 } |
1254 } |
1148 |
1255 |
1149 /** |
1256 /** |
1150 * Get random header image data from registered images in theme. |
1257 * Gets random header image data from registered images in theme. |
1151 * |
1258 * |
1152 * @since 3.4.0 |
1259 * @since 3.4.0 |
1153 * |
1260 * |
1154 * @access private |
1261 * @access private |
1155 * |
1262 * |
1156 * @global array $_wp_default_headers |
1263 * @global array $_wp_default_headers |
1157 * @staticvar object $_wp_random_header |
|
1158 * |
1264 * |
1159 * @return object |
1265 * @return object |
1160 */ |
1266 */ |
1161 function _get_random_header_data() { |
1267 function _get_random_header_data() { |
1162 static $_wp_random_header = null; |
1268 static $_wp_random_header = null; |
1164 if ( empty( $_wp_random_header ) ) { |
1270 if ( empty( $_wp_random_header ) ) { |
1165 global $_wp_default_headers; |
1271 global $_wp_default_headers; |
1166 $header_image_mod = get_theme_mod( 'header_image', '' ); |
1272 $header_image_mod = get_theme_mod( 'header_image', '' ); |
1167 $headers = array(); |
1273 $headers = array(); |
1168 |
1274 |
1169 if ( 'random-uploaded-image' == $header_image_mod ) { |
1275 if ( 'random-uploaded-image' === $header_image_mod ) { |
1170 $headers = get_uploaded_header_images(); |
1276 $headers = get_uploaded_header_images(); |
1171 } elseif ( ! empty( $_wp_default_headers ) ) { |
1277 } elseif ( ! empty( $_wp_default_headers ) ) { |
1172 if ( 'random-default-image' == $header_image_mod ) { |
1278 if ( 'random-default-image' === $header_image_mod ) { |
1173 $headers = $_wp_default_headers; |
1279 $headers = $_wp_default_headers; |
1174 } else { |
1280 } else { |
1175 if ( current_theme_supports( 'custom-header', 'random-default' ) ) { |
1281 if ( current_theme_supports( 'custom-header', 'random-default' ) ) { |
1176 $headers = $_wp_default_headers; |
1282 $headers = $_wp_default_headers; |
1177 } |
1283 } |
1185 $_wp_random_header = (object) $headers[ array_rand( $headers ) ]; |
1291 $_wp_random_header = (object) $headers[ array_rand( $headers ) ]; |
1186 |
1292 |
1187 $_wp_random_header->url = sprintf( $_wp_random_header->url, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1293 $_wp_random_header->url = sprintf( $_wp_random_header->url, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1188 $_wp_random_header->thumbnail_url = sprintf( $_wp_random_header->thumbnail_url, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1294 $_wp_random_header->thumbnail_url = sprintf( $_wp_random_header->thumbnail_url, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1189 } |
1295 } |
1296 |
|
1190 return $_wp_random_header; |
1297 return $_wp_random_header; |
1191 } |
1298 } |
1192 |
1299 |
1193 /** |
1300 /** |
1194 * Get random header image url from registered images in theme. |
1301 * Gets random header image URL from registered images in theme. |
1195 * |
1302 * |
1196 * @since 3.2.0 |
1303 * @since 3.2.0 |
1197 * |
1304 * |
1198 * @return string Path to header image |
1305 * @return string Path to header image. |
1199 */ |
1306 */ |
1200 function get_random_header_image() { |
1307 function get_random_header_image() { |
1201 $random_image = _get_random_header_data(); |
1308 $random_image = _get_random_header_data(); |
1309 |
|
1202 if ( empty( $random_image->url ) ) { |
1310 if ( empty( $random_image->url ) ) { |
1203 return ''; |
1311 return ''; |
1204 } |
1312 } |
1313 |
|
1205 return $random_image->url; |
1314 return $random_image->url; |
1206 } |
1315 } |
1207 |
1316 |
1208 /** |
1317 /** |
1209 * Check if random header image is in use. |
1318 * Checks if random header image is in use. |
1210 * |
1319 * |
1211 * Always true if user expressly chooses the option in Appearance > Header. |
1320 * Always true if user expressly chooses the option in Appearance > Header. |
1212 * Also true if theme has multiple header images registered, no specific header image |
1321 * Also true if theme has multiple header images registered, no specific header image |
1213 * is chosen, and theme turns on random headers with add_theme_support(). |
1322 * is chosen, and theme turns on random headers with add_theme_support(). |
1214 * |
1323 * |
1215 * @since 3.2.0 |
1324 * @since 3.2.0 |
1216 * |
1325 * |
1217 * @param string $type The random pool to use. any|default|uploaded |
1326 * @param string $type The random pool to use. Possible values include 'any', |
1327 * 'default', 'uploaded'. Default 'any'. |
|
1218 * @return bool |
1328 * @return bool |
1219 */ |
1329 */ |
1220 function is_random_header_image( $type = 'any' ) { |
1330 function is_random_header_image( $type = 'any' ) { |
1221 $header_image_mod = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) ); |
1331 $header_image_mod = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) ); |
1222 |
1332 |
1223 if ( 'any' == $type ) { |
1333 if ( 'any' === $type ) { |
1224 if ( 'random-default-image' == $header_image_mod || 'random-uploaded-image' == $header_image_mod || ( '' != get_random_header_image() && empty( $header_image_mod ) ) ) { |
1334 if ( 'random-default-image' === $header_image_mod |
1335 || 'random-uploaded-image' === $header_image_mod |
|
1336 || ( '' !== get_random_header_image() && empty( $header_image_mod ) ) |
|
1337 ) { |
|
1225 return true; |
1338 return true; |
1226 } |
1339 } |
1227 } else { |
1340 } else { |
1228 if ( "random-$type-image" == $header_image_mod ) { |
1341 if ( "random-$type-image" === $header_image_mod ) { |
1229 return true; |
1342 return true; |
1230 } elseif ( 'default' == $type && empty( $header_image_mod ) && '' != get_random_header_image() ) { |
1343 } elseif ( 'default' === $type && empty( $header_image_mod ) && '' !== get_random_header_image() ) { |
1231 return true; |
1344 return true; |
1232 } |
1345 } |
1233 } |
1346 } |
1234 |
1347 |
1235 return false; |
1348 return false; |
1236 } |
1349 } |
1237 |
1350 |
1238 /** |
1351 /** |
1239 * Display header image URL. |
1352 * Displays header image URL. |
1240 * |
1353 * |
1241 * @since 2.1.0 |
1354 * @since 2.1.0 |
1242 */ |
1355 */ |
1243 function header_image() { |
1356 function header_image() { |
1244 $image = get_header_image(); |
1357 $image = get_header_image(); |
1358 |
|
1245 if ( $image ) { |
1359 if ( $image ) { |
1246 echo esc_url( $image ); |
1360 echo esc_url( $image ); |
1247 } |
1361 } |
1248 } |
1362 } |
1249 |
1363 |
1250 /** |
1364 /** |
1251 * Get the header images uploaded for the current theme. |
1365 * Gets the header images uploaded for the current theme. |
1252 * |
1366 * |
1253 * @since 3.2.0 |
1367 * @since 3.2.0 |
1254 * |
1368 * |
1255 * @return array |
1369 * @return array |
1256 */ |
1370 */ |
1257 function get_uploaded_header_images() { |
1371 function get_uploaded_header_images() { |
1258 $header_images = array(); |
1372 $header_images = array(); |
1259 |
1373 |
1260 // @todo caching |
1374 // @todo Caching. |
1261 $headers = get_posts( |
1375 $headers = get_posts( |
1262 array( |
1376 array( |
1263 'post_type' => 'attachment', |
1377 'post_type' => 'attachment', |
1264 'meta_key' => '_wp_attachment_is_custom_header', |
1378 'meta_key' => '_wp_attachment_is_custom_header', |
1265 'meta_value' => get_option( 'stylesheet' ), |
1379 'meta_value' => get_option( 'stylesheet' ), |
1294 |
1408 |
1295 return $header_images; |
1409 return $header_images; |
1296 } |
1410 } |
1297 |
1411 |
1298 /** |
1412 /** |
1299 * Get the header image data. |
1413 * Gets the header image data. |
1300 * |
1414 * |
1301 * @since 3.4.0 |
1415 * @since 3.4.0 |
1302 * |
1416 * |
1303 * @global array $_wp_default_headers |
1417 * @global array $_wp_default_headers |
1304 * |
1418 * |
1310 if ( is_random_header_image() ) { |
1424 if ( is_random_header_image() ) { |
1311 $data = _get_random_header_data(); |
1425 $data = _get_random_header_data(); |
1312 } else { |
1426 } else { |
1313 $data = get_theme_mod( 'header_image_data' ); |
1427 $data = get_theme_mod( 'header_image_data' ); |
1314 if ( ! $data && current_theme_supports( 'custom-header', 'default-image' ) ) { |
1428 if ( ! $data && current_theme_supports( 'custom-header', 'default-image' ) ) { |
1315 $directory_args = array( get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1429 $directory_args = array( get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1316 $data = array(); |
1430 $data = array(); |
1317 $data['url'] = $data['thumbnail_url'] = vsprintf( get_theme_support( 'custom-header', 'default-image' ), $directory_args ); |
1431 $data['url'] = vsprintf( get_theme_support( 'custom-header', 'default-image' ), $directory_args ); |
1432 $data['thumbnail_url'] = $data['url']; |
|
1318 if ( ! empty( $_wp_default_headers ) ) { |
1433 if ( ! empty( $_wp_default_headers ) ) { |
1319 foreach ( (array) $_wp_default_headers as $default_header ) { |
1434 foreach ( (array) $_wp_default_headers as $default_header ) { |
1320 $url = vsprintf( $default_header['url'], $directory_args ); |
1435 $url = vsprintf( $default_header['url'], $directory_args ); |
1321 if ( $data['url'] == $url ) { |
1436 if ( $data['url'] == $url ) { |
1322 $data = $default_header; |
1437 $data = $default_header; |
1338 ); |
1453 ); |
1339 return (object) wp_parse_args( $data, $default ); |
1454 return (object) wp_parse_args( $data, $default ); |
1340 } |
1455 } |
1341 |
1456 |
1342 /** |
1457 /** |
1343 * Register a selection of default headers to be displayed by the custom header admin UI. |
1458 * Registers a selection of default headers to be displayed by the custom header admin UI. |
1344 * |
1459 * |
1345 * @since 3.0.0 |
1460 * @since 3.0.0 |
1346 * |
1461 * |
1347 * @global array $_wp_default_headers |
1462 * @global array $_wp_default_headers |
1348 * |
1463 * |
1349 * @param array $headers Array of headers keyed by a string id. The ids point to arrays containing 'url', 'thumbnail_url', and 'description' keys. |
1464 * @param array $headers Array of headers keyed by a string ID. The IDs point to arrays |
1465 * containing 'url', 'thumbnail_url', and 'description' keys. |
|
1350 */ |
1466 */ |
1351 function register_default_headers( $headers ) { |
1467 function register_default_headers( $headers ) { |
1352 global $_wp_default_headers; |
1468 global $_wp_default_headers; |
1353 |
1469 |
1354 $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); |
1470 $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); |
1355 } |
1471 } |
1356 |
1472 |
1357 /** |
1473 /** |
1358 * Unregister default headers. |
1474 * Unregisters default headers. |
1359 * |
1475 * |
1360 * This function must be called after register_default_headers() has already added the |
1476 * This function must be called after register_default_headers() has already added the |
1361 * header you want to remove. |
1477 * header you want to remove. |
1362 * |
1478 * |
1363 * @see register_default_headers() |
1479 * @see register_default_headers() |
1380 return false; |
1496 return false; |
1381 } |
1497 } |
1382 } |
1498 } |
1383 |
1499 |
1384 /** |
1500 /** |
1385 * Check whether a header video is set or not. |
1501 * Checks whether a header video is set or not. |
1386 * |
1502 * |
1387 * @since 4.7.0 |
1503 * @since 4.7.0 |
1388 * |
1504 * |
1389 * @see get_header_video_url() |
1505 * @see get_header_video_url() |
1390 * |
1506 * |
1393 function has_header_video() { |
1509 function has_header_video() { |
1394 return (bool) get_header_video_url(); |
1510 return (bool) get_header_video_url(); |
1395 } |
1511 } |
1396 |
1512 |
1397 /** |
1513 /** |
1398 * Retrieve header video URL for custom header. |
1514 * Retrieves header video URL for custom header. |
1399 * |
1515 * |
1400 * Uses a local video if present, or falls back to an external video. |
1516 * Uses a local video if present, or falls back to an external video. |
1401 * |
1517 * |
1402 * @since 4.7.0 |
1518 * @since 4.7.0 |
1403 * |
1519 * |
1404 * @return string|false Header video URL or false if there is no video. |
1520 * @return string|false Header video URL or false if there is no video. |
1405 */ |
1521 */ |
1406 function get_header_video_url() { |
1522 function get_header_video_url() { |
1407 $id = absint( get_theme_mod( 'header_video' ) ); |
1523 $id = absint( get_theme_mod( 'header_video' ) ); |
1408 $url = esc_url( get_theme_mod( 'external_header_video' ) ); |
|
1409 |
1524 |
1410 if ( $id ) { |
1525 if ( $id ) { |
1411 // Get the file URL from the attachment ID. |
1526 // Get the file URL from the attachment ID. |
1412 $url = wp_get_attachment_url( $id ); |
1527 $url = wp_get_attachment_url( $id ); |
1528 } else { |
|
1529 $url = get_theme_mod( 'external_header_video' ); |
|
1413 } |
1530 } |
1414 |
1531 |
1415 /** |
1532 /** |
1416 * Filters the header video URL. |
1533 * Filters the header video URL. |
1417 * |
1534 * |
1427 |
1544 |
1428 return esc_url_raw( set_url_scheme( $url ) ); |
1545 return esc_url_raw( set_url_scheme( $url ) ); |
1429 } |
1546 } |
1430 |
1547 |
1431 /** |
1548 /** |
1432 * Display header video URL. |
1549 * Displays header video URL. |
1433 * |
1550 * |
1434 * @since 4.7.0 |
1551 * @since 4.7.0 |
1435 */ |
1552 */ |
1436 function the_header_video_url() { |
1553 function the_header_video_url() { |
1437 $video = get_header_video_url(); |
1554 $video = get_header_video_url(); |
1555 |
|
1438 if ( $video ) { |
1556 if ( $video ) { |
1439 echo esc_url( $video ); |
1557 echo esc_url( $video ); |
1440 } |
1558 } |
1441 } |
1559 } |
1442 |
1560 |
1443 /** |
1561 /** |
1444 * Retrieve header video settings. |
1562 * Retrieves header video settings. |
1445 * |
1563 * |
1446 * @since 4.7.0 |
1564 * @since 4.7.0 |
1447 * |
1565 * |
1448 * @return array |
1566 * @return array |
1449 */ |
1567 */ |
1483 */ |
1601 */ |
1484 return apply_filters( 'header_video_settings', $settings ); |
1602 return apply_filters( 'header_video_settings', $settings ); |
1485 } |
1603 } |
1486 |
1604 |
1487 /** |
1605 /** |
1488 * Check whether a custom header is set or not. |
1606 * Checks whether a custom header is set or not. |
1489 * |
1607 * |
1490 * @since 4.7.0 |
1608 * @since 4.7.0 |
1491 * |
1609 * |
1492 * @return bool True if a custom header is set. False if not. |
1610 * @return bool True if a custom header is set. False if not. |
1493 */ |
1611 */ |
1518 } else { |
1636 } else { |
1519 $show_video = call_user_func( $video_active_cb ); |
1637 $show_video = call_user_func( $video_active_cb ); |
1520 } |
1638 } |
1521 |
1639 |
1522 /** |
1640 /** |
1523 * Modify whether the custom header video is eligible to show on the current page. |
1641 * Filters whether the custom header video is eligible to show on the current page. |
1524 * |
1642 * |
1525 * @since 4.7.0 |
1643 * @since 4.7.0 |
1526 * |
1644 * |
1527 * @param bool $show_video Whether the custom header video should be shown. Returns the value |
1645 * @param bool $show_video Whether the custom header video should be shown. Returns the value |
1528 * of the theme setting for the `custom-header`'s `video-active-callback`. |
1646 * of the theme setting for the `custom-header`'s `video-active-callback`. |
1530 */ |
1648 */ |
1531 return apply_filters( 'is_header_video_active', $show_video ); |
1649 return apply_filters( 'is_header_video_active', $show_video ); |
1532 } |
1650 } |
1533 |
1651 |
1534 /** |
1652 /** |
1535 * Retrieve the markup for a custom header. |
1653 * Retrieves the markup for a custom header. |
1536 * |
1654 * |
1537 * The container div will always be returned in the Customizer preview. |
1655 * The container div will always be returned in the Customizer preview. |
1538 * |
1656 * |
1539 * @since 4.7.0 |
1657 * @since 4.7.0 |
1540 * |
1658 * |
1550 get_header_image_tag() |
1668 get_header_image_tag() |
1551 ); |
1669 ); |
1552 } |
1670 } |
1553 |
1671 |
1554 /** |
1672 /** |
1555 * Print the markup for a custom header. |
1673 * Prints the markup for a custom header. |
1556 * |
1674 * |
1557 * A container div will always be printed in the Customizer preview. |
1675 * A container div will always be printed in the Customizer preview. |
1558 * |
1676 * |
1559 * @since 4.7.0 |
1677 * @since 4.7.0 |
1560 */ |
1678 */ |
1571 wp_localize_script( 'wp-custom-header', '_wpCustomHeaderSettings', get_header_video_settings() ); |
1689 wp_localize_script( 'wp-custom-header', '_wpCustomHeaderSettings', get_header_video_settings() ); |
1572 } |
1690 } |
1573 } |
1691 } |
1574 |
1692 |
1575 /** |
1693 /** |
1576 * Retrieve background image for custom background. |
1694 * Retrieves background image for custom background. |
1577 * |
1695 * |
1578 * @since 3.0.0 |
1696 * @since 3.0.0 |
1579 * |
1697 * |
1580 * @return string |
1698 * @return string |
1581 */ |
1699 */ |
1582 function get_background_image() { |
1700 function get_background_image() { |
1583 return get_theme_mod( 'background_image', get_theme_support( 'custom-background', 'default-image' ) ); |
1701 return get_theme_mod( 'background_image', get_theme_support( 'custom-background', 'default-image' ) ); |
1584 } |
1702 } |
1585 |
1703 |
1586 /** |
1704 /** |
1587 * Display background image path. |
1705 * Displays background image path. |
1588 * |
1706 * |
1589 * @since 3.0.0 |
1707 * @since 3.0.0 |
1590 */ |
1708 */ |
1591 function background_image() { |
1709 function background_image() { |
1592 echo get_background_image(); |
1710 echo get_background_image(); |
1593 } |
1711 } |
1594 |
1712 |
1595 /** |
1713 /** |
1596 * Retrieve value for custom background color. |
1714 * Retrieves value for custom background color. |
1597 * |
1715 * |
1598 * @since 3.0.0 |
1716 * @since 3.0.0 |
1599 * |
1717 * |
1600 * @return string |
1718 * @return string |
1601 */ |
1719 */ |
1602 function get_background_color() { |
1720 function get_background_color() { |
1603 return get_theme_mod( 'background_color', get_theme_support( 'custom-background', 'default-color' ) ); |
1721 return get_theme_mod( 'background_color', get_theme_support( 'custom-background', 'default-color' ) ); |
1604 } |
1722 } |
1605 |
1723 |
1606 /** |
1724 /** |
1607 * Display background color value. |
1725 * Displays background color value. |
1608 * |
1726 * |
1609 * @since 3.0.0 |
1727 * @since 3.0.0 |
1610 */ |
1728 */ |
1611 function background_color() { |
1729 function background_color() { |
1612 echo get_background_color(); |
1730 echo get_background_color(); |
1623 |
1741 |
1624 // $color is the saved custom color. |
1742 // $color is the saved custom color. |
1625 // A default has to be specified in style.css. It will not be printed here. |
1743 // A default has to be specified in style.css. It will not be printed here. |
1626 $color = get_background_color(); |
1744 $color = get_background_color(); |
1627 |
1745 |
1628 if ( $color === get_theme_support( 'custom-background', 'default-color' ) ) { |
1746 if ( get_theme_support( 'custom-background', 'default-color' ) === $color ) { |
1629 $color = false; |
1747 $color = false; |
1630 } |
1748 } |
1749 |
|
1750 $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; |
|
1631 |
1751 |
1632 if ( ! $background && ! $color ) { |
1752 if ( ! $background && ! $color ) { |
1633 if ( is_customize_preview() ) { |
1753 if ( is_customize_preview() ) { |
1634 echo '<style type="text/css" id="custom-background-css"></style>'; |
1754 printf( '<style%s id="custom-background-css"></style>', $type_attr ); |
1635 } |
1755 } |
1636 return; |
1756 return; |
1637 } |
1757 } |
1638 |
1758 |
1639 $style = $color ? "background-color: #$color;" : ''; |
1759 $style = $color ? "background-color: #$color;" : ''; |
1683 $attachment = " background-attachment: $attachment;"; |
1803 $attachment = " background-attachment: $attachment;"; |
1684 |
1804 |
1685 $style .= $image . $position . $size . $repeat . $attachment; |
1805 $style .= $image . $position . $size . $repeat . $attachment; |
1686 } |
1806 } |
1687 ?> |
1807 ?> |
1688 <style type="text/css" id="custom-background-css"> |
1808 <style<?php echo $type_attr; ?> id="custom-background-css"> |
1689 body.custom-background { <?php echo trim( $style ); ?> } |
1809 body.custom-background { <?php echo trim( $style ); ?> } |
1690 </style> |
1810 </style> |
1691 <?php |
1811 <?php |
1692 } |
1812 } |
1693 |
1813 |
1694 /** |
1814 /** |
1695 * Render the Custom CSS style element. |
1815 * Renders the Custom CSS style element. |
1696 * |
1816 * |
1697 * @since 4.7.0 |
1817 * @since 4.7.0 |
1698 */ |
1818 */ |
1699 function wp_custom_css_cb() { |
1819 function wp_custom_css_cb() { |
1700 $styles = wp_get_custom_css(); |
1820 $styles = wp_get_custom_css(); |
1701 if ( $styles || is_customize_preview() ) : |
1821 if ( $styles || is_customize_preview() ) : |
1822 $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; |
|
1702 ?> |
1823 ?> |
1703 <style type="text/css" id="wp-custom-css"> |
1824 <style<?php echo $type_attr; ?> id="wp-custom-css"> |
1704 <?php echo strip_tags( $styles ); // Note that esc_html() cannot be used because `div > span` is not interpreted properly. ?> |
1825 <?php echo strip_tags( $styles ); // Note that esc_html() cannot be used because `div > span` is not interpreted properly. ?> |
1705 </style> |
1826 </style> |
1706 <?php |
1827 <?php |
1707 endif; |
1828 endif; |
1708 } |
1829 } |
1709 |
1830 |
1710 /** |
1831 /** |
1711 * Fetch the `custom_css` post for a given theme. |
1832 * Fetches the `custom_css` post for a given theme. |
1712 * |
1833 * |
1713 * @since 4.7.0 |
1834 * @since 4.7.0 |
1714 * |
1835 * |
1715 * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme. |
1836 * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme. |
1716 * @return WP_Post|null The custom_css post or null if none exists. |
1837 * @return WP_Post|null The custom_css post or null if none exists. |
1757 |
1878 |
1758 return $post; |
1879 return $post; |
1759 } |
1880 } |
1760 |
1881 |
1761 /** |
1882 /** |
1762 * Fetch the saved Custom CSS content for rendering. |
1883 * Fetches the saved Custom CSS content for rendering. |
1763 * |
1884 * |
1764 * @since 4.7.0 |
1885 * @since 4.7.0 |
1765 * |
1886 * |
1766 * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme. |
1887 * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme. |
1767 * @return string The Custom CSS Post content. |
1888 * @return string The Custom CSS Post content. |
1790 |
1911 |
1791 return $css; |
1912 return $css; |
1792 } |
1913 } |
1793 |
1914 |
1794 /** |
1915 /** |
1795 * Update the `custom_css` post for a given theme. |
1916 * Updates the `custom_css` post for a given theme. |
1796 * |
1917 * |
1797 * Inserts a `custom_css` post when one doesn't yet exist. |
1918 * Inserts a `custom_css` post when one doesn't yet exist. |
1798 * |
1919 * |
1799 * @since 4.7.0 |
1920 * @since 4.7.0 |
1800 * |
1921 * |
1890 } |
2011 } |
1891 return get_post( $r ); |
2012 return get_post( $r ); |
1892 } |
2013 } |
1893 |
2014 |
1894 /** |
2015 /** |
1895 * Add callback for custom TinyMCE editor stylesheets. |
2016 * Adds callback for custom TinyMCE editor stylesheets. |
1896 * |
2017 * |
1897 * The parameter $stylesheet is the name of the stylesheet, relative to |
2018 * The parameter $stylesheet is the name of the stylesheet, relative to |
1898 * the theme root. It also accepts an array of stylesheets. |
2019 * the theme root. It also accepts an array of stylesheets. |
1899 * It is optional and defaults to 'editor-style.css'. |
2020 * It is optional and defaults to 'editor-style.css'. |
1900 * |
2021 * |
1912 * |
2033 * |
1913 * @param array|string $stylesheet Optional. Stylesheet name or array thereof, relative to theme root. |
2034 * @param array|string $stylesheet Optional. Stylesheet name or array thereof, relative to theme root. |
1914 * Defaults to 'editor-style.css' |
2035 * Defaults to 'editor-style.css' |
1915 */ |
2036 */ |
1916 function add_editor_style( $stylesheet = 'editor-style.css' ) { |
2037 function add_editor_style( $stylesheet = 'editor-style.css' ) { |
2038 global $editor_styles; |
|
2039 |
|
1917 add_theme_support( 'editor-style' ); |
2040 add_theme_support( 'editor-style' ); |
1918 |
2041 |
1919 if ( ! is_admin() ) { |
|
1920 return; |
|
1921 } |
|
1922 |
|
1923 global $editor_styles; |
|
1924 $editor_styles = (array) $editor_styles; |
2042 $editor_styles = (array) $editor_styles; |
1925 $stylesheet = (array) $stylesheet; |
2043 $stylesheet = (array) $stylesheet; |
2044 |
|
1926 if ( is_rtl() ) { |
2045 if ( is_rtl() ) { |
1927 $rtl_stylesheet = str_replace( '.css', '-rtl.css', $stylesheet[0] ); |
2046 $rtl_stylesheet = str_replace( '.css', '-rtl.css', $stylesheet[0] ); |
1928 $stylesheet[] = $rtl_stylesheet; |
2047 $stylesheet[] = $rtl_stylesheet; |
1929 } |
2048 } |
1930 |
2049 |
1950 } |
2069 } |
1951 return true; |
2070 return true; |
1952 } |
2071 } |
1953 |
2072 |
1954 /** |
2073 /** |
1955 * Retrieve any registered editor stylesheets |
2074 * Retrieves any registered editor stylesheet URLs. |
1956 * |
2075 * |
1957 * @since 4.0.0 |
2076 * @since 4.0.0 |
1958 * |
2077 * |
1959 * @global array $editor_styles Registered editor stylesheets |
2078 * @global array $editor_styles Registered editor stylesheets |
1960 * |
2079 * |
1961 * @return array If registered, a list of editor stylesheet URLs. |
2080 * @return string[] If registered, a list of editor stylesheet URLs. |
1962 */ |
2081 */ |
1963 function get_editor_stylesheets() { |
2082 function get_editor_stylesheets() { |
1964 $stylesheets = array(); |
2083 $stylesheets = array(); |
1965 // load editor_style.css if the current theme supports it |
2084 // Load editor_style.css if the current theme supports it. |
1966 if ( ! empty( $GLOBALS['editor_styles'] ) && is_array( $GLOBALS['editor_styles'] ) ) { |
2085 if ( ! empty( $GLOBALS['editor_styles'] ) && is_array( $GLOBALS['editor_styles'] ) ) { |
1967 $editor_styles = $GLOBALS['editor_styles']; |
2086 $editor_styles = $GLOBALS['editor_styles']; |
1968 |
2087 |
1969 $editor_styles = array_unique( array_filter( $editor_styles ) ); |
2088 $editor_styles = array_unique( array_filter( $editor_styles ) ); |
1970 $style_uri = get_stylesheet_directory_uri(); |
2089 $style_uri = get_stylesheet_directory_uri(); |
1996 } |
2115 } |
1997 } |
2116 } |
1998 } |
2117 } |
1999 |
2118 |
2000 /** |
2119 /** |
2001 * Filters the array of stylesheets applied to the editor. |
2120 * Filters the array of URLs of stylesheets applied to the editor. |
2002 * |
2121 * |
2003 * @since 4.3.0 |
2122 * @since 4.3.0 |
2004 * |
2123 * |
2005 * @param array $stylesheets Array of stylesheets to be applied to the editor. |
2124 * @param string[] $stylesheets Array of URLs of stylesheets to be applied to the editor. |
2006 */ |
2125 */ |
2007 return apply_filters( 'editor_stylesheets', $stylesheets ); |
2126 return apply_filters( 'editor_stylesheets', $stylesheets ); |
2008 } |
2127 } |
2009 |
2128 |
2010 /** |
2129 /** |
2011 * Expand a theme's starter content configuration using core-provided data. |
2130 * Expands a theme's starter content configuration using core-provided data. |
2012 * |
2131 * |
2013 * @since 4.7.0 |
2132 * @since 4.7.0 |
2014 * |
2133 * |
2015 * @return array Array of starter content. |
2134 * @return array Array of starter content. |
2016 */ |
2135 */ |
2032 '', |
2151 '', |
2033 array( |
2152 array( |
2034 '<strong>' . _x( 'Address', 'Theme starter content' ) . "</strong>\n", |
2153 '<strong>' . _x( 'Address', 'Theme starter content' ) . "</strong>\n", |
2035 _x( '123 Main Street', 'Theme starter content' ) . "\n" . _x( 'New York, NY 10001', 'Theme starter content' ) . "\n\n", |
2154 _x( '123 Main Street', 'Theme starter content' ) . "\n" . _x( 'New York, NY 10001', 'Theme starter content' ) . "\n\n", |
2036 '<strong>' . _x( 'Hours', 'Theme starter content' ) . "</strong>\n", |
2155 '<strong>' . _x( 'Hours', 'Theme starter content' ) . "</strong>\n", |
2037 _x( 'Monday—Friday: 9:00AM–5:00PM', 'Theme starter content' ) . "\n" . _x( 'Saturday & Sunday: 11:00AM–3:00PM', 'Theme starter content' ), |
2156 _x( 'Monday–Friday: 9:00AM–5:00PM', 'Theme starter content' ) . "\n" . _x( 'Saturday & Sunday: 11:00AM–3:00PM', 'Theme starter content' ), |
2038 ) |
2157 ) |
2039 ), |
2158 ), |
2040 'filter' => true, |
2159 'filter' => true, |
2041 'visual' => true, |
2160 'visual' => true, |
2042 ), |
2161 ), |
2097 'link_home' => array( |
2216 'link_home' => array( |
2098 'type' => 'custom', |
2217 'type' => 'custom', |
2099 'title' => _x( 'Home', 'Theme starter content' ), |
2218 'title' => _x( 'Home', 'Theme starter content' ), |
2100 'url' => home_url( '/' ), |
2219 'url' => home_url( '/' ), |
2101 ), |
2220 ), |
2102 'page_home' => array( // Deprecated in favor of link_home. |
2221 'page_home' => array( // Deprecated in favor of 'link_home'. |
2103 'type' => 'post_type', |
2222 'type' => 'post_type', |
2104 'object' => 'page', |
2223 'object' => 'page', |
2105 'object_id' => '{{home}}', |
2224 'object_id' => '{{home}}', |
2106 ), |
2225 ), |
2107 'page_about' => array( |
2226 'page_about' => array( |
2168 ), |
2287 ), |
2169 'posts' => array( |
2288 'posts' => array( |
2170 'home' => array( |
2289 'home' => array( |
2171 'post_type' => 'page', |
2290 'post_type' => 'page', |
2172 'post_title' => _x( 'Home', 'Theme starter content' ), |
2291 'post_title' => _x( 'Home', 'Theme starter content' ), |
2173 'post_content' => _x( 'Welcome to your site! This is your homepage, which is what most visitors will see when they come to your site for the first time.', 'Theme starter content' ), |
2292 'post_content' => sprintf( |
2293 "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", |
|
2294 _x( 'Welcome to your site! This is your homepage, which is what most visitors will see when they come to your site for the first time.', 'Theme starter content' ) |
|
2295 ), |
|
2174 ), |
2296 ), |
2175 'about' => array( |
2297 'about' => array( |
2176 'post_type' => 'page', |
2298 'post_type' => 'page', |
2177 'post_title' => _x( 'About', 'Theme starter content' ), |
2299 'post_title' => _x( 'About', 'Theme starter content' ), |
2178 'post_content' => _x( 'You might be an artist who would like to introduce yourself and your work here or maybe you’re a business with a mission to describe.', 'Theme starter content' ), |
2300 'post_content' => sprintf( |
2301 "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", |
|
2302 _x( 'You might be an artist who would like to introduce yourself and your work here or maybe you’re a business with a mission to describe.', 'Theme starter content' ) |
|
2303 ), |
|
2179 ), |
2304 ), |
2180 'contact' => array( |
2305 'contact' => array( |
2181 'post_type' => 'page', |
2306 'post_type' => 'page', |
2182 'post_title' => _x( 'Contact', 'Theme starter content' ), |
2307 'post_title' => _x( 'Contact', 'Theme starter content' ), |
2183 'post_content' => _x( 'This is a page with some basic contact information, such as an address and phone number. You might also try a plugin to add a contact form.', 'Theme starter content' ), |
2308 'post_content' => sprintf( |
2309 "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", |
|
2310 _x( 'This is a page with some basic contact information, such as an address and phone number. You might also try a plugin to add a contact form.', 'Theme starter content' ) |
|
2311 ), |
|
2184 ), |
2312 ), |
2185 'blog' => array( |
2313 'blog' => array( |
2186 'post_type' => 'page', |
2314 'post_type' => 'page', |
2187 'post_title' => _x( 'Blog', 'Theme starter content' ), |
2315 'post_title' => _x( 'Blog', 'Theme starter content' ), |
2188 ), |
2316 ), |
2192 ), |
2320 ), |
2193 |
2321 |
2194 'homepage-section' => array( |
2322 'homepage-section' => array( |
2195 'post_type' => 'page', |
2323 'post_type' => 'page', |
2196 'post_title' => _x( 'A homepage section', 'Theme starter content' ), |
2324 'post_title' => _x( 'A homepage section', 'Theme starter content' ), |
2197 'post_content' => _x( 'This is an example of a homepage section. Homepage sections can be any page other than the homepage itself, including the page that shows your latest blog posts.', 'Theme starter content' ), |
2325 'post_content' => sprintf( |
2326 "<!-- wp:paragraph -->\n<p>%s</p>\n<!-- /wp:paragraph -->", |
|
2327 _x( 'This is an example of a homepage section. Homepage sections can be any page other than the homepage itself, including the page that shows your latest blog posts.', 'Theme starter content' ) |
|
2328 ), |
|
2198 ), |
2329 ), |
2199 ), |
2330 ), |
2200 ); |
2331 ); |
2201 |
2332 |
2202 $content = array(); |
2333 $content = array(); |
2265 $content[ $type ][ $id ] = $item; |
2396 $content[ $type ][ $id ] = $item; |
2266 } |
2397 } |
2267 } |
2398 } |
2268 break; |
2399 break; |
2269 |
2400 |
2270 // All that's left now are posts (besides attachments). Not a default case for the sake of clarity and future work. |
2401 // All that's left now are posts (besides attachments). |
2402 // Not a default case for the sake of clarity and future work. |
|
2271 case 'posts': |
2403 case 'posts': |
2272 foreach ( $config[ $type ] as $id => $item ) { |
2404 foreach ( $config[ $type ] as $id => $item ) { |
2273 if ( is_array( $item ) ) { |
2405 if ( is_array( $item ) ) { |
2274 |
2406 |
2275 // Item extends core content. |
2407 // Item extends core content. |
2316 * |
2448 * |
2317 * Must be called in the theme's functions.php file to work. |
2449 * Must be called in the theme's functions.php file to work. |
2318 * If attached to a hook, it must be {@see 'after_setup_theme'}. |
2450 * If attached to a hook, it must be {@see 'after_setup_theme'}. |
2319 * The {@see 'init'} hook may be too late for some features. |
2451 * The {@see 'init'} hook may be too late for some features. |
2320 * |
2452 * |
2453 * Example usage: |
|
2454 * |
|
2455 * add_theme_support( 'title-tag' ); |
|
2456 * add_theme_support( 'custom-logo', array( |
|
2457 * 'height' => 480, |
|
2458 * 'width' => 720, |
|
2459 * ) ); |
|
2460 * |
|
2321 * @since 2.9.0 |
2461 * @since 2.9.0 |
2322 * @since 3.6.0 The `html5` feature was added |
2462 * @since 3.4.0 The `custom-header-uploads` feature was deprecated. |
2323 * @since 3.9.0 The `html5` feature now also accepts 'gallery' and 'caption' |
2463 * @since 3.6.0 The `html5` feature was added. |
2324 * @since 4.1.0 The `title-tag` feature was added |
2464 * @since 3.9.0 The `html5` feature now also accepts 'gallery' and 'caption'. |
2325 * @since 4.5.0 The `customize-selective-refresh-widgets` feature was added |
2465 * @since 4.1.0 The `title-tag` feature was added. |
2326 * @since 4.7.0 The `starter-content` feature was added |
2466 * @since 4.5.0 The `customize-selective-refresh-widgets` feature was added. |
2467 * @since 4.7.0 The `starter-content` feature was added. |
|
2327 * @since 5.0.0 The `responsive-embeds`, `align-wide`, `dark-editor-style`, `disable-custom-colors`, |
2468 * @since 5.0.0 The `responsive-embeds`, `align-wide`, `dark-editor-style`, `disable-custom-colors`, |
2328 * `disable-custom-font-sizes`, `editor-color-pallete`, `editor-font-sizes`, |
2469 * `disable-custom-font-sizes`, `editor-color-palette`, `editor-font-sizes`, |
2329 * `editor-styles`, and `wp-block-styles` features were added. |
2470 * `editor-styles`, and `wp-block-styles` features were added. |
2471 * @since 5.3.0 The `html5` feature now also accepts 'script' and 'style'. |
|
2472 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
|
2473 * by adding it to the function signature. |
|
2474 * @since 5.5.0 The `core-block-patterns` feature was added and is enabled by default. |
|
2475 * @since 5.5.0 The `custom-logo` feature now also accepts 'unlink-homepage-logo'. |
|
2330 * |
2476 * |
2331 * @global array $_wp_theme_features |
2477 * @global array $_wp_theme_features |
2332 * |
2478 * |
2333 * @param string $feature The feature being added. Likely core values include 'post-formats', |
2479 * @param string $feature The feature being added. Likely core values include 'post-formats', 'post-thumbnails', |
2334 * 'post-thumbnails', 'html5', 'custom-logo', 'custom-header-uploads', |
2480 * 'custom-header', 'custom-background', 'custom-logo', 'menus', 'automatic-feed-links', |
2335 * 'custom-header', 'custom-background', 'title-tag', 'starter-content', |
2481 * 'html5', 'title-tag', 'customize-selective-refresh-widgets', 'starter-content', |
2336 * 'responsive-embeds', etc. |
2482 * 'responsive-embeds', 'align-wide', 'dark-editor-style', 'disable-custom-colors', |
2337 * @param mixed $args,... Optional extra arguments to pass along with certain features. |
2483 * 'disable-custom-font-sizes', 'editor-color-palette', 'editor-font-sizes', |
2484 * 'editor-styles', 'wp-block-styles', and 'core-block-patterns'. |
|
2485 * @param mixed ...$args Optional extra arguments to pass along with certain features. |
|
2338 * @return void|bool False on failure, void otherwise. |
2486 * @return void|bool False on failure, void otherwise. |
2339 */ |
2487 */ |
2340 function add_theme_support( $feature ) { |
2488 function add_theme_support( $feature, ...$args ) { |
2341 global $_wp_theme_features; |
2489 global $_wp_theme_features; |
2342 |
2490 |
2343 if ( func_num_args() == 1 ) { |
2491 if ( ! $args ) { |
2344 $args = true; |
2492 $args = true; |
2345 } else { |
|
2346 $args = array_slice( func_get_args(), 1 ); |
|
2347 } |
2493 } |
2348 |
2494 |
2349 switch ( $feature ) { |
2495 switch ( $feature ) { |
2350 case 'post-thumbnails': |
2496 case 'post-thumbnails': |
2351 // All post types are already supported. |
2497 // All post types are already supported. |
2355 |
2501 |
2356 /* |
2502 /* |
2357 * Merge post types with any that already declared their support |
2503 * Merge post types with any that already declared their support |
2358 * for post thumbnails. |
2504 * for post thumbnails. |
2359 */ |
2505 */ |
2360 if ( is_array( $args[0] ) && isset( $_wp_theme_features['post-thumbnails'] ) ) { |
2506 if ( isset( $args[0] ) && is_array( $args[0] ) && isset( $_wp_theme_features['post-thumbnails'] ) ) { |
2361 $args[0] = array_unique( array_merge( $_wp_theme_features['post-thumbnails'][0], $args[0] ) ); |
2507 $args[0] = array_unique( array_merge( $_wp_theme_features['post-thumbnails'][0], $args[0] ) ); |
2362 } |
2508 } |
2363 |
2509 |
2364 break; |
2510 break; |
2365 |
2511 |
2366 case 'post-formats': |
2512 case 'post-formats': |
2367 if ( is_array( $args[0] ) ) { |
2513 if ( isset( $args[0] ) && is_array( $args[0] ) ) { |
2368 $post_formats = get_post_format_slugs(); |
2514 $post_formats = get_post_format_slugs(); |
2369 unset( $post_formats['standard'] ); |
2515 unset( $post_formats['standard'] ); |
2370 |
2516 |
2371 $args[0] = array_intersect( $args[0], array_keys( $post_formats ) ); |
2517 $args[0] = array_intersect( $args[0], array_keys( $post_formats ) ); |
2372 } |
2518 } |
2375 case 'html5': |
2521 case 'html5': |
2376 // You can't just pass 'html5', you need to pass an array of types. |
2522 // You can't just pass 'html5', you need to pass an array of types. |
2377 if ( empty( $args[0] ) ) { |
2523 if ( empty( $args[0] ) ) { |
2378 // Build an array of types for back-compat. |
2524 // Build an array of types for back-compat. |
2379 $args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) ); |
2525 $args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) ); |
2380 } elseif ( ! is_array( $args[0] ) ) { |
2526 } elseif ( ! isset( $args[0] ) || ! is_array( $args[0] ) ) { |
2381 _doing_it_wrong( "add_theme_support( 'html5' )", __( 'You need to pass an array of types.' ), '3.6.1' ); |
2527 _doing_it_wrong( "add_theme_support( 'html5' )", __( 'You need to pass an array of types.' ), '3.6.1' ); |
2382 return false; |
2528 return false; |
2383 } |
2529 } |
2384 |
2530 |
2385 // Calling 'html5' again merges, rather than overwrites. |
2531 // Calling 'html5' again merges, rather than overwrites. |
2387 $args[0] = array_merge( $_wp_theme_features['html5'][0], $args[0] ); |
2533 $args[0] = array_merge( $_wp_theme_features['html5'][0], $args[0] ); |
2388 } |
2534 } |
2389 break; |
2535 break; |
2390 |
2536 |
2391 case 'custom-logo': |
2537 case 'custom-logo': |
2392 if ( ! is_array( $args ) ) { |
2538 if ( true === $args ) { |
2393 $args = array( 0 => array() ); |
2539 $args = array( 0 => array() ); |
2394 } |
2540 } |
2395 $defaults = array( |
2541 $defaults = array( |
2396 'width' => null, |
2542 'width' => null, |
2397 'height' => null, |
2543 'height' => null, |
2398 'flex-width' => false, |
2544 'flex-width' => false, |
2399 'flex-height' => false, |
2545 'flex-height' => false, |
2400 'header-text' => '', |
2546 'header-text' => '', |
2547 'unlink-homepage-logo' => false, |
|
2401 ); |
2548 ); |
2402 $args[0] = wp_parse_args( array_intersect_key( $args[0], $defaults ), $defaults ); |
2549 $args[0] = wp_parse_args( array_intersect_key( $args[0], $defaults ), $defaults ); |
2403 |
2550 |
2404 // Allow full flexibility if no size is specified. |
2551 // Allow full flexibility if no size is specified. |
2405 if ( is_null( $args[0]['width'] ) && is_null( $args[0]['height'] ) ) { |
2552 if ( is_null( $args[0]['width'] ) && is_null( $args[0]['height'] ) ) { |
2410 |
2557 |
2411 case 'custom-header-uploads': |
2558 case 'custom-header-uploads': |
2412 return add_theme_support( 'custom-header', array( 'uploads' => true ) ); |
2559 return add_theme_support( 'custom-header', array( 'uploads' => true ) ); |
2413 |
2560 |
2414 case 'custom-header': |
2561 case 'custom-header': |
2415 if ( ! is_array( $args ) ) { |
2562 if ( true === $args ) { |
2416 $args = array( 0 => array() ); |
2563 $args = array( 0 => array() ); |
2417 } |
2564 } |
2418 |
2565 |
2419 $defaults = array( |
2566 $defaults = array( |
2420 'default-image' => '', |
2567 'default-image' => '', |
2446 // This will cause all constants to be defined, as each arg will then be set to the default. |
2593 // This will cause all constants to be defined, as each arg will then be set to the default. |
2447 if ( $jit ) { |
2594 if ( $jit ) { |
2448 $args[0] = wp_parse_args( $args[0], $defaults ); |
2595 $args[0] = wp_parse_args( $args[0], $defaults ); |
2449 } |
2596 } |
2450 |
2597 |
2451 // If a constant was defined, use that value. Otherwise, define the constant to ensure |
2598 /* |
2452 // the constant is always accurate (and is not defined later, overriding our value). |
2599 * If a constant was defined, use that value. Otherwise, define the constant to ensure |
2453 // As stated above, the first value wins. |
2600 * the constant is always accurate (and is not defined later, overriding our value). |
2454 // Once we get to wp_loaded (just-in-time), define any constants we haven't already. |
2601 * As stated above, the first value wins. |
2455 // Constants are lame. Don't reference them. This is just for backward compatibility. |
2602 * Once we get to wp_loaded (just-in-time), define any constants we haven't already. |
2603 * Constants are lame. Don't reference them. This is just for backward compatibility. |
|
2604 */ |
|
2456 |
2605 |
2457 if ( defined( 'NO_HEADER_TEXT' ) ) { |
2606 if ( defined( 'NO_HEADER_TEXT' ) ) { |
2458 $args[0]['header-text'] = ! NO_HEADER_TEXT; |
2607 $args[0]['header-text'] = ! NO_HEADER_TEXT; |
2459 } elseif ( isset( $args[0]['header-text'] ) ) { |
2608 } elseif ( isset( $args[0]['header-text'] ) ) { |
2460 define( 'NO_HEADER_TEXT', empty( $args[0]['header-text'] ) ); |
2609 define( 'NO_HEADER_TEXT', empty( $args[0]['header-text'] ) ); |
2500 } |
2649 } |
2501 |
2650 |
2502 break; |
2651 break; |
2503 |
2652 |
2504 case 'custom-background': |
2653 case 'custom-background': |
2505 if ( ! is_array( $args ) ) { |
2654 if ( true === $args ) { |
2506 $args = array( 0 => array() ); |
2655 $args = array( 0 => array() ); |
2507 } |
2656 } |
2508 |
2657 |
2509 $defaults = array( |
2658 $defaults = array( |
2510 'default-image' => '', |
2659 'default-image' => '', |
2548 |
2697 |
2549 // Ensure that 'title-tag' is accessible in the admin. |
2698 // Ensure that 'title-tag' is accessible in the admin. |
2550 case 'title-tag': |
2699 case 'title-tag': |
2551 // Can be called in functions.php but must happen before wp_loaded, i.e. not in header.php. |
2700 // Can be called in functions.php but must happen before wp_loaded, i.e. not in header.php. |
2552 if ( did_action( 'wp_loaded' ) ) { |
2701 if ( did_action( 'wp_loaded' ) ) { |
2553 /* translators: 1: title-tag, 2: wp_loaded */ |
|
2554 _doing_it_wrong( |
2702 _doing_it_wrong( |
2555 "add_theme_support( 'title-tag' )", |
2703 "add_theme_support( 'title-tag' )", |
2556 sprintf( |
2704 sprintf( |
2705 /* translators: 1: title-tag, 2: wp_loaded */ |
|
2557 __( 'Theme support for %1$s should be registered before the %2$s hook.' ), |
2706 __( 'Theme support for %1$s should be registered before the %2$s hook.' ), |
2558 '<code>title-tag</code>', |
2707 '<code>title-tag</code>', |
2559 '<code>wp_loaded</code>' |
2708 '<code>wp_loaded</code>' |
2560 ), |
2709 ), |
2561 '4.1.0' |
2710 '4.1.0' |
2588 if ( $args[0]['wp-head-callback'] ) { |
2737 if ( $args[0]['wp-head-callback'] ) { |
2589 add_action( 'wp_head', $args[0]['wp-head-callback'] ); |
2738 add_action( 'wp_head', $args[0]['wp-head-callback'] ); |
2590 } |
2739 } |
2591 |
2740 |
2592 if ( is_admin() ) { |
2741 if ( is_admin() ) { |
2593 require_once( ABSPATH . 'wp-admin/custom-header.php' ); |
2742 require_once ABSPATH . 'wp-admin/includes/class-custom-image-header.php'; |
2594 $custom_image_header = new Custom_Image_Header( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] ); |
2743 $custom_image_header = new Custom_Image_Header( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] ); |
2595 } |
2744 } |
2596 } |
2745 } |
2597 |
2746 |
2598 if ( current_theme_supports( 'custom-background' ) ) { |
2747 if ( current_theme_supports( 'custom-background' ) ) { |
2601 |
2750 |
2602 $args = get_theme_support( 'custom-background' ); |
2751 $args = get_theme_support( 'custom-background' ); |
2603 add_action( 'wp_head', $args[0]['wp-head-callback'] ); |
2752 add_action( 'wp_head', $args[0]['wp-head-callback'] ); |
2604 |
2753 |
2605 if ( is_admin() ) { |
2754 if ( is_admin() ) { |
2606 require_once( ABSPATH . 'wp-admin/custom-background.php' ); |
2755 require_once ABSPATH . 'wp-admin/includes/class-custom-background.php'; |
2607 $custom_background = new Custom_Background( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] ); |
2756 $custom_background = new Custom_Background( $args[0]['admin-head-callback'], $args[0]['admin-preview-callback'] ); |
2608 } |
2757 } |
2609 } |
2758 } |
2610 } |
2759 } |
2611 |
2760 |
2619 if ( ! current_theme_supports( 'custom-header', 'header-text' ) && get_theme_support( 'custom-logo', 'header-text' ) && ! get_theme_mod( 'header_text', true ) ) { |
2768 if ( ! current_theme_supports( 'custom-header', 'header-text' ) && get_theme_support( 'custom-logo', 'header-text' ) && ! get_theme_mod( 'header_text', true ) ) { |
2620 $classes = (array) get_theme_support( 'custom-logo', 'header-text' ); |
2769 $classes = (array) get_theme_support( 'custom-logo', 'header-text' ); |
2621 $classes = array_map( 'sanitize_html_class', $classes ); |
2770 $classes = array_map( 'sanitize_html_class', $classes ); |
2622 $classes = '.' . implode( ', .', $classes ); |
2771 $classes = '.' . implode( ', .', $classes ); |
2623 |
2772 |
2773 $type_attr = current_theme_supports( 'html5', 'style' ) ? '' : ' type="text/css"'; |
|
2624 ?> |
2774 ?> |
2625 <!-- Custom Logo: hide header text --> |
2775 <!-- Custom Logo: hide header text --> |
2626 <style id="custom-logo-css" type="text/css"> |
2776 <style id="custom-logo-css"<?php echo $type_attr; ?>> |
2627 <?php echo $classes; ?> { |
2777 <?php echo $classes; ?> { |
2628 position: absolute; |
2778 position: absolute; |
2629 clip: rect(1px, 1px, 1px, 1px); |
2779 clip: rect(1px, 1px, 1px, 1px); |
2630 } |
2780 } |
2631 </style> |
2781 </style> |
2632 <?php |
2782 <?php |
2633 } |
2783 } |
2634 } |
2784 } |
2635 |
2785 |
2636 /** |
2786 /** |
2637 * Gets the theme support arguments passed when registering that support |
2787 * Gets the theme support arguments passed when registering that support. |
2788 * |
|
2789 * Example usage: |
|
2790 * |
|
2791 * get_theme_support( 'custom-logo' ); |
|
2792 * get_theme_support( 'custom-header', 'width' ); |
|
2638 * |
2793 * |
2639 * @since 3.1.0 |
2794 * @since 3.1.0 |
2795 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
|
2796 * by adding it to the function signature. |
|
2640 * |
2797 * |
2641 * @global array $_wp_theme_features |
2798 * @global array $_wp_theme_features |
2642 * |
2799 * |
2643 * @param string $feature The feature to check. |
2800 * @param string $feature The feature to check. See add_theme_support() for the list |
2801 * of possible values. |
|
2802 * @param mixed ...$args Optional extra arguments to be checked against certain features. |
|
2644 * @return mixed The array of extra arguments or the value for the registered feature. |
2803 * @return mixed The array of extra arguments or the value for the registered feature. |
2645 */ |
2804 */ |
2646 function get_theme_support( $feature ) { |
2805 function get_theme_support( $feature, ...$args ) { |
2647 global $_wp_theme_features; |
2806 global $_wp_theme_features; |
2648 if ( ! isset( $_wp_theme_features[ $feature ] ) ) { |
2807 if ( ! isset( $_wp_theme_features[ $feature ] ) ) { |
2649 return false; |
2808 return false; |
2650 } |
2809 } |
2651 |
2810 |
2652 if ( func_num_args() <= 1 ) { |
2811 if ( ! $args ) { |
2653 return $_wp_theme_features[ $feature ]; |
2812 return $_wp_theme_features[ $feature ]; |
2654 } |
2813 } |
2655 |
2814 |
2656 $args = array_slice( func_get_args(), 1 ); |
|
2657 switch ( $feature ) { |
2815 switch ( $feature ) { |
2658 case 'custom-logo': |
2816 case 'custom-logo': |
2659 case 'custom-header': |
2817 case 'custom-header': |
2660 case 'custom-background': |
2818 case 'custom-background': |
2661 if ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) ) { |
2819 if ( isset( $_wp_theme_features[ $feature ][0][ $args[0] ] ) ) { |
2673 * |
2831 * |
2674 * Should be called in the theme's functions.php file. Generally would |
2832 * Should be called in the theme's functions.php file. Generally would |
2675 * be used for child themes to override support from the parent theme. |
2833 * be used for child themes to override support from the parent theme. |
2676 * |
2834 * |
2677 * @since 3.0.0 |
2835 * @since 3.0.0 |
2836 * |
|
2678 * @see add_theme_support() |
2837 * @see add_theme_support() |
2679 * @param string $feature The feature being removed. |
2838 * |
2839 * @param string $feature The feature being removed. See add_theme_support() for the list |
|
2840 * of possible values. |
|
2680 * @return bool|void Whether feature was removed. |
2841 * @return bool|void Whether feature was removed. |
2681 */ |
2842 */ |
2682 function remove_theme_support( $feature ) { |
2843 function remove_theme_support( $feature ) { |
2683 // Blacklist: for internal registrations not used directly by themes. |
2844 // Do not remove internal registrations that are not used directly by themes. |
2684 if ( in_array( $feature, array( 'editor-style', 'widgets', 'menus' ) ) ) { |
2845 if ( in_array( $feature, array( 'editor-style', 'widgets', 'menus' ), true ) ) { |
2685 return false; |
2846 return false; |
2686 } |
2847 } |
2687 |
2848 |
2688 return _remove_theme_support( $feature ); |
2849 return _remove_theme_support( $feature ); |
2689 } |
2850 } |
2690 |
2851 |
2691 /** |
2852 /** |
2692 * Do not use. Removes theme support internally, ignorant of the blacklist. |
2853 * Do not use. Removes theme support internally without knowledge of those not used |
2854 * by themes directly. |
|
2693 * |
2855 * |
2694 * @access private |
2856 * @access private |
2695 * @since 3.1.0 |
2857 * @since 3.1.0 |
2696 * |
|
2697 * @global array $_wp_theme_features |
2858 * @global array $_wp_theme_features |
2698 * @global Custom_Image_Header $custom_image_header |
2859 * @global Custom_Image_Header $custom_image_header |
2699 * @global Custom_Background $custom_background |
2860 * @global Custom_Background $custom_background |
2700 * |
2861 * |
2701 * @param string $feature |
2862 * @param string $feature The feature being removed. See add_theme_support() for the list |
2863 * of possible values. |
|
2864 * @return bool True if support was removed, false if the feature was not registered. |
|
2702 */ |
2865 */ |
2703 function _remove_theme_support( $feature ) { |
2866 function _remove_theme_support( $feature ) { |
2704 global $_wp_theme_features; |
2867 global $_wp_theme_features; |
2705 |
2868 |
2706 switch ( $feature ) { |
2869 switch ( $feature ) { |
2743 unset( $GLOBALS['custom_background'] ); |
2906 unset( $GLOBALS['custom_background'] ); |
2744 break; |
2907 break; |
2745 } |
2908 } |
2746 |
2909 |
2747 unset( $_wp_theme_features[ $feature ] ); |
2910 unset( $_wp_theme_features[ $feature ] ); |
2911 |
|
2748 return true; |
2912 return true; |
2749 } |
2913 } |
2750 |
2914 |
2751 /** |
2915 /** |
2752 * Checks a theme's support for a given feature. |
2916 * Checks a theme's support for a given feature. |
2753 * |
2917 * |
2918 * Example usage: |
|
2919 * |
|
2920 * current_theme_supports( 'custom-logo' ); |
|
2921 * current_theme_supports( 'html5', 'comment-form' ); |
|
2922 * |
|
2754 * @since 2.9.0 |
2923 * @since 2.9.0 |
2924 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
|
2925 * by adding it to the function signature. |
|
2755 * |
2926 * |
2756 * @global array $_wp_theme_features |
2927 * @global array $_wp_theme_features |
2757 * |
2928 * |
2758 * @param string $feature The feature being checked. |
2929 * @param string $feature The feature being checked. See add_theme_support() for the list |
2930 * of possible values. |
|
2931 * @param mixed ...$args Optional extra arguments to be checked against certain features. |
|
2759 * @return bool True if the current theme supports the feature, false otherwise. |
2932 * @return bool True if the current theme supports the feature, false otherwise. |
2760 */ |
2933 */ |
2761 function current_theme_supports( $feature ) { |
2934 function current_theme_supports( $feature, ...$args ) { |
2762 global $_wp_theme_features; |
2935 global $_wp_theme_features; |
2763 |
2936 |
2764 if ( 'custom-header-uploads' == $feature ) { |
2937 if ( 'custom-header-uploads' === $feature ) { |
2765 return current_theme_supports( 'custom-header', 'uploads' ); |
2938 return current_theme_supports( 'custom-header', 'uploads' ); |
2766 } |
2939 } |
2767 |
2940 |
2768 if ( ! isset( $_wp_theme_features[ $feature ] ) ) { |
2941 if ( ! isset( $_wp_theme_features[ $feature ] ) ) { |
2769 return false; |
2942 return false; |
2770 } |
2943 } |
2771 |
2944 |
2772 // If no args passed then no extra checks need be performed |
2945 // If no args passed then no extra checks need be performed. |
2773 if ( func_num_args() <= 1 ) { |
2946 if ( ! $args ) { |
2774 return true; |
2947 return true; |
2775 } |
2948 } |
2776 |
|
2777 $args = array_slice( func_get_args(), 1 ); |
|
2778 |
2949 |
2779 switch ( $feature ) { |
2950 switch ( $feature ) { |
2780 case 'post-thumbnails': |
2951 case 'post-thumbnails': |
2781 // post-thumbnails can be registered for only certain content/post types by passing |
2952 /* |
2782 // an array of types to add_theme_support(). If no array was passed, then |
2953 * post-thumbnails can be registered for only certain content/post types |
2783 // any type is accepted |
2954 * by passing an array of types to add_theme_support(). |
2784 if ( true === $_wp_theme_features[ $feature ] ) { // Registered for all types |
2955 * If no array was passed, then any type is accepted. |
2956 */ |
|
2957 if ( true === $_wp_theme_features[ $feature ] ) { // Registered for all types. |
|
2785 return true; |
2958 return true; |
2786 } |
2959 } |
2787 $content_type = $args[0]; |
2960 $content_type = $args[0]; |
2788 return in_array( $content_type, $_wp_theme_features[ $feature ][0] ); |
2961 return in_array( $content_type, $_wp_theme_features[ $feature ][0], true ); |
2789 |
2962 |
2790 case 'html5': |
2963 case 'html5': |
2791 case 'post-formats': |
2964 case 'post-formats': |
2792 // specific post formats can be registered by passing an array of types to |
2965 /* |
2793 // add_theme_support() |
2966 * Specific post formats can be registered by passing an array of types |
2794 |
2967 * to add_theme_support(). |
2795 // Specific areas of HTML5 support *must* be passed via an array to add_theme_support() |
2968 * |
2796 |
2969 * Specific areas of HTML5 support *must* be passed via an array to add_theme_support(). |
2970 */ |
|
2797 $type = $args[0]; |
2971 $type = $args[0]; |
2798 return in_array( $type, $_wp_theme_features[ $feature ][0] ); |
2972 return in_array( $type, $_wp_theme_features[ $feature ][0], true ); |
2799 |
2973 |
2800 case 'custom-logo': |
2974 case 'custom-logo': |
2801 case 'custom-header': |
2975 case 'custom-header': |
2802 case 'custom-background': |
2976 case 'custom-background': |
2803 // Specific capabilities can be registered by passing an array to add_theme_support(). |
2977 // Specific capabilities can be registered by passing an array to add_theme_support(). |
2805 } |
2979 } |
2806 |
2980 |
2807 /** |
2981 /** |
2808 * Filters whether the current theme supports a specific feature. |
2982 * Filters whether the current theme supports a specific feature. |
2809 * |
2983 * |
2810 * The dynamic portion of the hook name, `$feature`, refers to the specific theme |
2984 * The dynamic portion of the hook name, `$feature`, refers to the specific |
2811 * feature. Possible values include 'post-formats', 'post-thumbnails', 'custom-background', |
2985 * theme feature. See add_theme_support() for the list of possible values. |
2812 * 'custom-header', 'menus', 'automatic-feed-links', 'html5', |
|
2813 * 'starter-content', and 'customize-selective-refresh-widgets'. |
|
2814 * |
2986 * |
2815 * @since 3.4.0 |
2987 * @since 3.4.0 |
2816 * |
2988 * |
2817 * @param bool true Whether the current theme supports the given feature. Default true. |
2989 * @param bool $supports Whether the current theme supports the given feature. Default true. |
2818 * @param array $args Array of arguments for the feature. |
2990 * @param array $args Array of arguments for the feature. |
2819 * @param string $feature The theme feature. |
2991 * @param string $feature The theme feature. |
2820 */ |
2992 */ |
2821 return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); |
2993 return apply_filters( "current_theme_supports-{$feature}", true, $args, $_wp_theme_features[ $feature ] ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores |
2822 } |
2994 } |
2823 |
2995 |
2824 /** |
2996 /** |
2825 * Checks a theme's support for a given feature before loading the functions which implement it. |
2997 * Checks a theme's support for a given feature before loading the functions which implement it. |
2826 * |
2998 * |
2827 * @since 2.9.0 |
2999 * @since 2.9.0 |
2828 * |
3000 * |
2829 * @param string $feature The feature being checked. |
3001 * @param string $feature The feature being checked. See add_theme_support() for the list |
3002 * of possible values. |
|
2830 * @param string $include Path to the file. |
3003 * @param string $include Path to the file. |
2831 * @return bool True if the current theme supports the supplied feature, false otherwise. |
3004 * @return bool True if the current theme supports the supplied feature, false otherwise. |
2832 */ |
3005 */ |
2833 function require_if_theme_supports( $feature, $include ) { |
3006 function require_if_theme_supports( $feature, $include ) { |
2834 if ( current_theme_supports( $feature ) ) { |
3007 if ( current_theme_supports( $feature ) ) { |
2835 require( $include ); |
3008 require $include; |
2836 return true; |
3009 return true; |
2837 } |
3010 } |
2838 return false; |
3011 return false; |
3012 } |
|
3013 |
|
3014 /** |
|
3015 * Registers a theme feature for use in add_theme_support(). |
|
3016 * |
|
3017 * This does not indicate that the current theme supports the feature, it only describes |
|
3018 * the feature's supported options. |
|
3019 * |
|
3020 * @since 5.5.0 |
|
3021 * |
|
3022 * @see add_theme_support() |
|
3023 * |
|
3024 * @global array $_wp_registered_theme_features |
|
3025 * |
|
3026 * @param string $feature The name uniquely identifying the feature. See add_theme_support() |
|
3027 * for the list of possible values. |
|
3028 * @param array $args { |
|
3029 * Data used to describe the theme. |
|
3030 * |
|
3031 * @type string $type The type of data associated with this feature. |
|
3032 * Valid values are 'string', 'boolean', 'integer', |
|
3033 * 'number', 'array', and 'object'. Defaults to 'boolean'. |
|
3034 * @type boolean $variadic Does this feature utilize the variadic support |
|
3035 * of add_theme_support(), or are all arguments specified |
|
3036 * as the second parameter. Must be used with the "array" type. |
|
3037 * @type string $description A short description of the feature. Included in |
|
3038 * the Themes REST API schema. Intended for developers. |
|
3039 * @type bool|array $show_in_rest { |
|
3040 * Whether this feature should be included in the Themes REST API endpoint. |
|
3041 * Defaults to not being included. When registering an 'array' or 'object' type, |
|
3042 * this argument must be an array with the 'schema' key. |
|
3043 * |
|
3044 * @type array $schema Specifies the JSON Schema definition describing |
|
3045 * the feature. If any objects in the schema do not include |
|
3046 * the 'additionalProperties' keyword, it is set to false. |
|
3047 * @type string $name An alternate name to be used as the property name |
|
3048 * in the REST API. |
|
3049 * @type callable $prepare_callback A function used to format the theme support in the REST API. |
|
3050 * Receives the raw theme support value. |
|
3051 * } |
|
3052 * } |
|
3053 * @return true|WP_Error True if the theme feature was successfully registered, a WP_Error object if not. |
|
3054 */ |
|
3055 function register_theme_feature( $feature, $args = array() ) { |
|
3056 global $_wp_registered_theme_features; |
|
3057 |
|
3058 if ( ! is_array( $_wp_registered_theme_features ) ) { |
|
3059 $_wp_registered_theme_features = array(); |
|
3060 } |
|
3061 |
|
3062 $defaults = array( |
|
3063 'type' => 'boolean', |
|
3064 'variadic' => false, |
|
3065 'description' => '', |
|
3066 'show_in_rest' => false, |
|
3067 ); |
|
3068 |
|
3069 $args = wp_parse_args( $args, $defaults ); |
|
3070 |
|
3071 if ( true === $args['show_in_rest'] ) { |
|
3072 $args['show_in_rest'] = array(); |
|
3073 } |
|
3074 |
|
3075 if ( is_array( $args['show_in_rest'] ) ) { |
|
3076 $args['show_in_rest'] = wp_parse_args( |
|
3077 $args['show_in_rest'], |
|
3078 array( |
|
3079 'schema' => array(), |
|
3080 'name' => $feature, |
|
3081 'prepare_callback' => null, |
|
3082 ) |
|
3083 ); |
|
3084 } |
|
3085 |
|
3086 if ( ! in_array( $args['type'], array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { |
|
3087 return new WP_Error( |
|
3088 'invalid_type', |
|
3089 __( 'The feature "type" is not valid JSON Schema type.' ) |
|
3090 ); |
|
3091 } |
|
3092 |
|
3093 if ( true === $args['variadic'] && 'array' !== $args['type'] ) { |
|
3094 return new WP_Error( |
|
3095 'variadic_must_be_array', |
|
3096 __( 'When registering a "variadic" theme feature, the "type" must be an "array".' ) |
|
3097 ); |
|
3098 } |
|
3099 |
|
3100 if ( false !== $args['show_in_rest'] && in_array( $args['type'], array( 'array', 'object' ), true ) ) { |
|
3101 if ( ! is_array( $args['show_in_rest'] ) || empty( $args['show_in_rest']['schema'] ) ) { |
|
3102 return new WP_Error( |
|
3103 'missing_schema', |
|
3104 __( 'When registering an "array" or "object" feature to show in the REST API, the feature\'s schema must also be defined.' ) |
|
3105 ); |
|
3106 } |
|
3107 |
|
3108 if ( 'array' === $args['type'] && ! isset( $args['show_in_rest']['schema']['items'] ) ) { |
|
3109 return new WP_Error( |
|
3110 'missing_schema_items', |
|
3111 __( 'When registering an "array" feature, the feature\'s schema must include the "items" keyword.' ) |
|
3112 ); |
|
3113 } |
|
3114 |
|
3115 if ( 'object' === $args['type'] && ! isset( $args['show_in_rest']['schema']['properties'] ) ) { |
|
3116 return new WP_Error( |
|
3117 'missing_schema_properties', |
|
3118 __( 'When registering an "object" feature, the feature\'s schema must include the "properties" keyword.' ) |
|
3119 ); |
|
3120 } |
|
3121 } |
|
3122 |
|
3123 if ( is_array( $args['show_in_rest'] ) ) { |
|
3124 if ( isset( $args['show_in_rest']['prepare_callback'] ) && ! is_callable( $args['show_in_rest']['prepare_callback'] ) ) { |
|
3125 return new WP_Error( |
|
3126 'invalid_rest_prepare_callback', |
|
3127 sprintf( |
|
3128 /* translators: %s: prepare_callback */ |
|
3129 __( 'The "%s" must be a callable function.' ), |
|
3130 'prepare_callback' |
|
3131 ) |
|
3132 ); |
|
3133 } |
|
3134 |
|
3135 $args['show_in_rest']['schema'] = wp_parse_args( |
|
3136 $args['show_in_rest']['schema'], |
|
3137 array( |
|
3138 'description' => $args['description'], |
|
3139 'type' => $args['type'], |
|
3140 'default' => false, |
|
3141 ) |
|
3142 ); |
|
3143 |
|
3144 if ( is_bool( $args['show_in_rest']['schema']['default'] ) |
|
3145 && ! in_array( 'boolean', (array) $args['show_in_rest']['schema']['type'], true ) |
|
3146 ) { |
|
3147 // Automatically include the "boolean" type when the default value is a boolean. |
|
3148 $args['show_in_rest']['schema']['type'] = (array) $args['show_in_rest']['schema']['type']; |
|
3149 array_unshift( $args['show_in_rest']['schema']['type'], 'boolean' ); |
|
3150 } |
|
3151 |
|
3152 $args['show_in_rest']['schema'] = rest_default_additional_properties_to_false( $args['show_in_rest']['schema'] ); |
|
3153 } |
|
3154 |
|
3155 $_wp_registered_theme_features[ $feature ] = $args; |
|
3156 |
|
3157 return true; |
|
3158 } |
|
3159 |
|
3160 /** |
|
3161 * Gets the list of registered theme features. |
|
3162 * |
|
3163 * @since 5.5.0 |
|
3164 * |
|
3165 * @global array $_wp_registered_theme_features |
|
3166 * |
|
3167 * @return array[] List of theme features, keyed by their name. |
|
3168 */ |
|
3169 function get_registered_theme_features() { |
|
3170 global $_wp_registered_theme_features; |
|
3171 |
|
3172 if ( ! is_array( $_wp_registered_theme_features ) ) { |
|
3173 return array(); |
|
3174 } |
|
3175 |
|
3176 return $_wp_registered_theme_features; |
|
3177 } |
|
3178 |
|
3179 /** |
|
3180 * Gets the registration config for a theme feature. |
|
3181 * |
|
3182 * @since 5.5.0 |
|
3183 * |
|
3184 * @global array $_wp_registered_theme_features |
|
3185 * |
|
3186 * @param string $feature The feature name. See add_theme_support() for the list |
|
3187 * of possible values. |
|
3188 * @return array|null The registration args, or null if the feature was not registered. |
|
3189 */ |
|
3190 function get_registered_theme_feature( $feature ) { |
|
3191 global $_wp_registered_theme_features; |
|
3192 |
|
3193 if ( ! is_array( $_wp_registered_theme_features ) ) { |
|
3194 return null; |
|
3195 } |
|
3196 |
|
3197 return isset( $_wp_registered_theme_features[ $feature ] ) ? $_wp_registered_theme_features[ $feature ] : null; |
|
2839 } |
3198 } |
2840 |
3199 |
2841 /** |
3200 /** |
2842 * Checks an attachment being deleted to see if it's a header or background image. |
3201 * Checks an attachment being deleted to see if it's a header or background image. |
2843 * |
3202 * |
2847 * @access private |
3206 * @access private |
2848 * @since 3.0.0 |
3207 * @since 3.0.0 |
2849 * @since 4.3.0 Also removes `header_image_data`. |
3208 * @since 4.3.0 Also removes `header_image_data`. |
2850 * @since 4.5.0 Also removes custom logo theme mods. |
3209 * @since 4.5.0 Also removes custom logo theme mods. |
2851 * |
3210 * |
2852 * @param int $id The attachment id. |
3211 * @param int $id The attachment ID. |
2853 */ |
3212 */ |
2854 function _delete_attachment_theme_mod( $id ) { |
3213 function _delete_attachment_theme_mod( $id ) { |
2855 $attachment_image = wp_get_attachment_url( $id ); |
3214 $attachment_image = wp_get_attachment_url( $id ); |
2856 $header_image = get_header_image(); |
3215 $header_image = get_header_image(); |
2857 $background_image = get_background_image(); |
3216 $background_image = get_background_image(); |
2878 * See {@see 'after_switch_theme'}. |
3237 * See {@see 'after_switch_theme'}. |
2879 * |
3238 * |
2880 * @since 3.3.0 |
3239 * @since 3.3.0 |
2881 */ |
3240 */ |
2882 function check_theme_switched() { |
3241 function check_theme_switched() { |
2883 if ( $stylesheet = get_option( 'theme_switched' ) ) { |
3242 $stylesheet = get_option( 'theme_switched' ); |
3243 if ( $stylesheet ) { |
|
2884 $old_theme = wp_get_theme( $stylesheet ); |
3244 $old_theme = wp_get_theme( $stylesheet ); |
2885 |
3245 |
2886 // Prevent widget & menu mapping from running since Customizer already called it up front |
3246 // Prevent widget & menu mapping from running since Customizer already called it up front. |
2887 if ( get_option( 'theme_switched_via_customizer' ) ) { |
3247 if ( get_option( 'theme_switched_via_customizer' ) ) { |
2888 remove_action( 'after_switch_theme', '_wp_menus_changed' ); |
3248 remove_action( 'after_switch_theme', '_wp_menus_changed' ); |
2889 remove_action( 'after_switch_theme', '_wp_sidebars_changed' ); |
3249 remove_action( 'after_switch_theme', '_wp_sidebars_changed' ); |
2890 update_option( 'theme_switched_via_customizer', false ); |
3250 update_option( 'theme_switched_via_customizer', false ); |
2891 } |
3251 } |
2928 * |
3288 * |
2929 * @global WP_Customize_Manager $wp_customize |
3289 * @global WP_Customize_Manager $wp_customize |
2930 */ |
3290 */ |
2931 function _wp_customize_include() { |
3291 function _wp_customize_include() { |
2932 |
3292 |
2933 $is_customize_admin_page = ( is_admin() && 'customize.php' == basename( $_SERVER['PHP_SELF'] ) ); |
3293 $is_customize_admin_page = ( is_admin() && 'customize.php' === basename( $_SERVER['PHP_SELF'] ) ); |
2934 $should_include = ( |
3294 $should_include = ( |
2935 $is_customize_admin_page |
3295 $is_customize_admin_page |
2936 || |
3296 || |
2937 ( isset( $_REQUEST['wp_customize'] ) && 'on' == $_REQUEST['wp_customize'] ) |
3297 ( isset( $_REQUEST['wp_customize'] ) && 'on' === $_REQUEST['wp_customize'] ) |
2938 || |
3298 || |
2939 ( ! empty( $_GET['customize_changeset_uuid'] ) || ! empty( $_POST['customize_changeset_uuid'] ) ) |
3299 ( ! empty( $_GET['customize_changeset_uuid'] ) || ! empty( $_POST['customize_changeset_uuid'] ) ) |
2940 ); |
3300 ); |
2941 |
3301 |
2942 if ( ! $should_include ) { |
3302 if ( ! $should_include ) { |
2953 wp_array_slice_assoc( $_GET, $keys ), |
3313 wp_array_slice_assoc( $_GET, $keys ), |
2954 wp_array_slice_assoc( $_POST, $keys ) |
3314 wp_array_slice_assoc( $_POST, $keys ) |
2955 ); |
3315 ); |
2956 |
3316 |
2957 $theme = null; |
3317 $theme = null; |
2958 $changeset_uuid = false; // Value false indicates UUID should be determined after_setup_theme to either re-use existing saved changeset or else generate a new UUID if none exists. |
3318 $autosaved = null; |
2959 $messenger_channel = null; |
3319 $messenger_channel = null; |
2960 $autosaved = null; |
3320 |
2961 $branching = false; // Set initially fo false since defaults to true for back-compat; can be overridden via the customize_changeset_branching filter. |
3321 // Value false indicates UUID should be determined after_setup_theme |
3322 // to either re-use existing saved changeset or else generate a new UUID if none exists. |
|
3323 $changeset_uuid = false; |
|
3324 |
|
3325 // Set initially fo false since defaults to true for back-compat; |
|
3326 // can be overridden via the customize_changeset_branching filter. |
|
3327 $branching = false; |
|
2962 |
3328 |
2963 if ( $is_customize_admin_page && isset( $input_vars['changeset_uuid'] ) ) { |
3329 if ( $is_customize_admin_page && isset( $input_vars['changeset_uuid'] ) ) { |
2964 $changeset_uuid = sanitize_key( $input_vars['changeset_uuid'] ); |
3330 $changeset_uuid = sanitize_key( $input_vars['changeset_uuid'] ); |
2965 } elseif ( ! empty( $input_vars['customize_changeset_uuid'] ) ) { |
3331 } elseif ( ! empty( $input_vars['customize_changeset_uuid'] ) ) { |
2966 $changeset_uuid = sanitize_key( $input_vars['customize_changeset_uuid'] ); |
3332 $changeset_uuid = sanitize_key( $input_vars['customize_changeset_uuid'] ); |
3080 * |
3446 * |
3081 * This is needed to prevent the post_name from being dropped when the post is |
3447 * This is needed to prevent the post_name from being dropped when the post is |
3082 * transitioned into pending status by a contributor. |
3448 * transitioned into pending status by a contributor. |
3083 * |
3449 * |
3084 * @since 4.7.0 |
3450 * @since 4.7.0 |
3451 * |
|
3085 * @see wp_insert_post() |
3452 * @see wp_insert_post() |
3086 * |
3453 * |
3087 * @param array $post_data An array of slashed post data. |
3454 * @param array $post_data An array of slashed post data. |
3088 * @param array $supplied_post_data An array of sanitized, but otherwise unmodified post data. |
3455 * @param array $supplied_post_data An array of sanitized, but otherwise unmodified post data. |
3089 * @returns array Filtered data. |
3456 * @return array Filtered data. |
3090 */ |
3457 */ |
3091 function _wp_customize_changeset_filter_insert_post_data( $post_data, $supplied_post_data ) { |
3458 function _wp_customize_changeset_filter_insert_post_data( $post_data, $supplied_post_data ) { |
3092 if ( isset( $post_data['post_type'] ) && 'customize_changeset' === $post_data['post_type'] ) { |
3459 if ( isset( $post_data['post_type'] ) && 'customize_changeset' === $post_data['post_type'] ) { |
3093 |
3460 |
3094 // Prevent post_name from being dropped, such as when contributor saves a changeset post as pending. |
3461 // Prevent post_name from being dropped, such as when contributor saves a changeset post as pending. |
3142 * |
3509 * |
3143 * @param string $stylesheet Optional. Theme to customize. Defaults to current theme. |
3510 * @param string $stylesheet Optional. Theme to customize. Defaults to current theme. |
3144 * The theme's stylesheet will be urlencoded if necessary. |
3511 * The theme's stylesheet will be urlencoded if necessary. |
3145 * @return string |
3512 * @return string |
3146 */ |
3513 */ |
3147 function wp_customize_url( $stylesheet = null ) { |
3514 function wp_customize_url( $stylesheet = '' ) { |
3148 $url = admin_url( 'customize.php' ); |
3515 $url = admin_url( 'customize.php' ); |
3149 if ( $stylesheet ) { |
3516 if ( $stylesheet ) { |
3150 $url .= '?theme=' . urlencode( $stylesheet ); |
3517 $url .= '?theme=' . urlencode( $stylesheet ); |
3151 } |
3518 } |
3152 return esc_url( $url ); |
3519 return esc_url( $url ); |
3165 * It is also recommended that you add the "no-customize-support" class |
3532 * It is also recommended that you add the "no-customize-support" class |
3166 * to the body tag by default. |
3533 * to the body tag by default. |
3167 * |
3534 * |
3168 * @since 3.4.0 |
3535 * @since 3.4.0 |
3169 * @since 4.7.0 Support for IE8 and below is explicitly removed via conditional comments. |
3536 * @since 4.7.0 Support for IE8 and below is explicitly removed via conditional comments. |
3537 * @since 5.5.0 IE8 and older are no longer supported. |
|
3170 */ |
3538 */ |
3171 function wp_customize_support_script() { |
3539 function wp_customize_support_script() { |
3172 $admin_origin = parse_url( admin_url() ); |
3540 $admin_origin = parse_url( admin_url() ); |
3173 $home_origin = parse_url( home_url() ); |
3541 $home_origin = parse_url( home_url() ); |
3174 $cross_domain = ( strtolower( $admin_origin['host'] ) != strtolower( $home_origin['host'] ) ); |
3542 $cross_domain = ( strtolower( $admin_origin['host'] ) != strtolower( $home_origin['host'] ) ); |
3175 |
3543 $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : ' type="text/javascript"'; |
3176 ?> |
3544 ?> |
3177 <!--[if lte IE 8]> |
3545 <script<?php echo $type_attr; ?>> |
3178 <script type="text/javascript"> |
3546 (function() { |
3179 document.body.className = document.body.className.replace( /(^|\s)(no-)?customize-support(?=\s|$)/, '' ) + ' no-customize-support'; |
3547 var request, b = document.body, c = 'className', cs = 'customize-support', rcs = new RegExp('(^|\\s+)(no-)?'+cs+'(\\s+|$)'); |
3180 </script> |
3548 |
3181 <![endif]--> |
3549 <?php if ( $cross_domain ) : ?> |
3182 <!--[if gte IE 9]><!--> |
3550 request = (function(){ var xhr = new XMLHttpRequest(); return ('withCredentials' in xhr); })(); |
3183 <script type="text/javascript"> |
3551 <?php else : ?> |
3184 (function() { |
3552 request = true; |
3185 var request, b = document.body, c = 'className', cs = 'customize-support', rcs = new RegExp('(^|\\s+)(no-)?'+cs+'(\\s+|$)'); |
3553 <?php endif; ?> |
3186 |
3554 |
3187 <?php if ( $cross_domain ) : ?> |
3555 b[c] = b[c].replace( rcs, ' ' ); |
3188 request = (function(){ var xhr = new XMLHttpRequest(); return ('withCredentials' in xhr); })(); |
3556 // The customizer requires postMessage and CORS (if the site is cross domain). |
3189 <?php else : ?> |
3557 b[c] += ( window.postMessage && request ? ' ' : ' no-' ) + cs; |
3190 request = true; |
3558 }()); |
3191 <?php endif; ?> |
3559 </script> |
3192 |
|
3193 b[c] = b[c].replace( rcs, ' ' ); |
|
3194 // The customizer requires postMessage and CORS (if the site is cross domain) |
|
3195 b[c] += ( window.postMessage && request ? ' ' : ' no-' ) + cs; |
|
3196 }()); |
|
3197 </script> |
|
3198 <!--<![endif]--> |
|
3199 <?php |
3560 <?php |
3200 } |
3561 } |
3201 |
3562 |
3202 /** |
3563 /** |
3203 * Whether the site is being previewed in the Customizer. |
3564 * Whether the site is being previewed in the Customizer. |
3213 |
3574 |
3214 return ( $wp_customize instanceof WP_Customize_Manager ) && $wp_customize->is_preview(); |
3575 return ( $wp_customize instanceof WP_Customize_Manager ) && $wp_customize->is_preview(); |
3215 } |
3576 } |
3216 |
3577 |
3217 /** |
3578 /** |
3218 * Make sure that auto-draft posts get their post_date bumped or status changed to draft to prevent premature garbage-collection. |
3579 * Makes sure that auto-draft posts get their post_date bumped or status changed to draft to prevent premature garbage-collection. |
3219 * |
3580 * |
3220 * When a changeset is updated but remains an auto-draft, ensure the post_date |
3581 * When a changeset is updated but remains an auto-draft, ensure the post_date |
3221 * for the auto-draft posts remains the same so that it will be |
3582 * for the auto-draft posts remains the same so that it will be |
3222 * garbage-collected at the same time by `wp_delete_auto_drafts()`. Otherwise, |
3583 * garbage-collected at the same time by `wp_delete_auto_drafts()`. Otherwise, |
3223 * if the changeset is updated to be a draft then update the posts |
3584 * if the changeset is updated to be a draft then update the posts |
3234 * |
3595 * |
3235 * @since 4.8.0 |
3596 * @since 4.8.0 |
3236 * @access private |
3597 * @access private |
3237 * @see wp_delete_auto_drafts() |
3598 * @see wp_delete_auto_drafts() |
3238 * |
3599 * |
3600 * @global wpdb $wpdb WordPress database abstraction object. |
|
3601 * |
|
3239 * @param string $new_status Transition to this post status. |
3602 * @param string $new_status Transition to this post status. |
3240 * @param string $old_status Previous post status. |
3603 * @param string $old_status Previous post status. |
3241 * @param \WP_Post $post Post data. |
3604 * @param \WP_Post $post Post data. |
3242 * @global wpdb $wpdb |
|
3243 */ |
3605 */ |
3244 function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) { |
3606 function _wp_keep_alive_customize_changeset_dependent_auto_drafts( $new_status, $old_status, $post ) { |
3245 global $wpdb; |
3607 global $wpdb; |
3246 unset( $old_status ); |
3608 unset( $old_status ); |
3247 |
3609 |
3302 array( 'ID' => $post_id ) |
3664 array( 'ID' => $post_id ) |
3303 ); |
3665 ); |
3304 clean_post_cache( $post_id ); |
3666 clean_post_cache( $post_id ); |
3305 } |
3667 } |
3306 } |
3668 } |
3669 |
|
3670 /** |
|
3671 * Creates the initial theme features when the 'setup_theme' action is fired. |
|
3672 * |
|
3673 * See {@see 'setup_theme'}. |
|
3674 * |
|
3675 * @since 5.5.0 |
|
3676 */ |
|
3677 function create_initial_theme_features() { |
|
3678 register_theme_feature( |
|
3679 'align-wide', |
|
3680 array( |
|
3681 'description' => __( 'Whether theme opts in to wide alignment CSS class.' ), |
|
3682 'show_in_rest' => true, |
|
3683 ) |
|
3684 ); |
|
3685 register_theme_feature( |
|
3686 'automatic-feed-links', |
|
3687 array( |
|
3688 'description' => __( 'Whether posts and comments RSS feed links are added to head.' ), |
|
3689 'show_in_rest' => true, |
|
3690 ) |
|
3691 ); |
|
3692 register_theme_feature( |
|
3693 'custom-background', |
|
3694 array( |
|
3695 'description' => __( 'Custom background if defined by the theme.' ), |
|
3696 'type' => 'object', |
|
3697 'show_in_rest' => array( |
|
3698 'schema' => array( |
|
3699 'properties' => array( |
|
3700 'default-image' => array( |
|
3701 'type' => 'string', |
|
3702 'format' => 'uri', |
|
3703 ), |
|
3704 'default-preset' => array( |
|
3705 'type' => 'string', |
|
3706 'enum' => array( |
|
3707 'default', |
|
3708 'fill', |
|
3709 'fit', |
|
3710 'repeat', |
|
3711 'custom', |
|
3712 ), |
|
3713 ), |
|
3714 'default-position-x' => array( |
|
3715 'type' => 'string', |
|
3716 'enum' => array( |
|
3717 'left', |
|
3718 'center', |
|
3719 'right', |
|
3720 ), |
|
3721 ), |
|
3722 'default-position-y' => array( |
|
3723 'type' => 'string', |
|
3724 'enum' => array( |
|
3725 'left', |
|
3726 'center', |
|
3727 'right', |
|
3728 ), |
|
3729 ), |
|
3730 'default-size' => array( |
|
3731 'type' => 'string', |
|
3732 'enum' => array( |
|
3733 'auto', |
|
3734 'contain', |
|
3735 'cover', |
|
3736 ), |
|
3737 ), |
|
3738 'default-repeat' => array( |
|
3739 'type' => 'string', |
|
3740 'enum' => array( |
|
3741 'repeat-x', |
|
3742 'repeat-y', |
|
3743 'repeat', |
|
3744 'no-repeat', |
|
3745 ), |
|
3746 ), |
|
3747 'default-attachment' => array( |
|
3748 'type' => 'string', |
|
3749 'enum' => array( |
|
3750 'scroll', |
|
3751 'fixed', |
|
3752 ), |
|
3753 ), |
|
3754 'default-color' => array( |
|
3755 'type' => 'string', |
|
3756 ), |
|
3757 ), |
|
3758 ), |
|
3759 ), |
|
3760 ) |
|
3761 ); |
|
3762 register_theme_feature( |
|
3763 'custom-header', |
|
3764 array( |
|
3765 'description' => __( 'Custom header if defined by the theme.' ), |
|
3766 'type' => 'object', |
|
3767 'show_in_rest' => array( |
|
3768 'schema' => array( |
|
3769 'properties' => array( |
|
3770 'default-image' => array( |
|
3771 'type' => 'string', |
|
3772 'format' => 'uri', |
|
3773 ), |
|
3774 'random-default' => array( |
|
3775 'type' => 'boolean', |
|
3776 ), |
|
3777 'width' => array( |
|
3778 'type' => 'integer', |
|
3779 ), |
|
3780 'height' => array( |
|
3781 'type' => 'integer', |
|
3782 ), |
|
3783 'flex-height' => array( |
|
3784 'type' => 'boolean', |
|
3785 ), |
|
3786 'flex-width' => array( |
|
3787 'type' => 'boolean', |
|
3788 ), |
|
3789 'default-text-color' => array( |
|
3790 'type' => 'string', |
|
3791 ), |
|
3792 'header-text' => array( |
|
3793 'type' => 'boolean', |
|
3794 ), |
|
3795 'uploads' => array( |
|
3796 'type' => 'boolean', |
|
3797 ), |
|
3798 'video' => array( |
|
3799 'type' => 'boolean', |
|
3800 ), |
|
3801 ), |
|
3802 ), |
|
3803 ), |
|
3804 ) |
|
3805 ); |
|
3806 register_theme_feature( |
|
3807 'custom-logo', |
|
3808 array( |
|
3809 'type' => 'object', |
|
3810 'description' => __( 'Custom logo if defined by the theme.' ), |
|
3811 'show_in_rest' => array( |
|
3812 'schema' => array( |
|
3813 'properties' => array( |
|
3814 'width' => array( |
|
3815 'type' => 'integer', |
|
3816 ), |
|
3817 'height' => array( |
|
3818 'type' => 'integer', |
|
3819 ), |
|
3820 'flex-width' => array( |
|
3821 'type' => 'boolean', |
|
3822 ), |
|
3823 'flex-height' => array( |
|
3824 'type' => 'boolean', |
|
3825 ), |
|
3826 'header-text' => array( |
|
3827 'type' => 'array', |
|
3828 'items' => array( |
|
3829 'type' => 'string', |
|
3830 ), |
|
3831 ), |
|
3832 'unlink-homepage-logo' => array( |
|
3833 'type' => 'boolean', |
|
3834 ), |
|
3835 ), |
|
3836 ), |
|
3837 ), |
|
3838 ) |
|
3839 ); |
|
3840 register_theme_feature( |
|
3841 'customize-selective-refresh-widgets', |
|
3842 array( |
|
3843 'description' => __( 'Whether the theme enables Selective Refresh for Widgets being managed with the Customizer.' ), |
|
3844 'show_in_rest' => true, |
|
3845 ) |
|
3846 ); |
|
3847 register_theme_feature( |
|
3848 'dark-editor-style', |
|
3849 array( |
|
3850 'description' => __( 'Whether theme opts in to the dark editor style UI.' ), |
|
3851 'show_in_rest' => true, |
|
3852 ) |
|
3853 ); |
|
3854 register_theme_feature( |
|
3855 'disable-custom-colors', |
|
3856 array( |
|
3857 'description' => __( 'Whether the theme disables custom colors.' ), |
|
3858 'show_in_rest' => true, |
|
3859 ) |
|
3860 ); |
|
3861 register_theme_feature( |
|
3862 'disable-custom-font-sizes', |
|
3863 array( |
|
3864 'description' => __( 'Whether the theme disables custom font sizes.' ), |
|
3865 'show_in_rest' => true, |
|
3866 ) |
|
3867 ); |
|
3868 register_theme_feature( |
|
3869 'disable-custom-gradients', |
|
3870 array( |
|
3871 'description' => __( 'Whether the theme disables custom gradients.' ), |
|
3872 'show_in_rest' => true, |
|
3873 ) |
|
3874 ); |
|
3875 register_theme_feature( |
|
3876 'editor-color-palette', |
|
3877 array( |
|
3878 'type' => 'array', |
|
3879 'description' => __( 'Custom color palette if defined by the theme.' ), |
|
3880 'show_in_rest' => array( |
|
3881 'schema' => array( |
|
3882 'items' => array( |
|
3883 'type' => 'object', |
|
3884 'properties' => array( |
|
3885 'name' => array( |
|
3886 'type' => 'string', |
|
3887 ), |
|
3888 'slug' => array( |
|
3889 'type' => 'string', |
|
3890 ), |
|
3891 'color' => array( |
|
3892 'type' => 'string', |
|
3893 ), |
|
3894 ), |
|
3895 ), |
|
3896 ), |
|
3897 ), |
|
3898 ) |
|
3899 ); |
|
3900 register_theme_feature( |
|
3901 'editor-font-sizes', |
|
3902 array( |
|
3903 'type' => 'array', |
|
3904 'description' => __( 'Custom font sizes if defined by the theme.' ), |
|
3905 'show_in_rest' => array( |
|
3906 'schema' => array( |
|
3907 'items' => array( |
|
3908 'type' => 'object', |
|
3909 'properties' => array( |
|
3910 'name' => array( |
|
3911 'type' => 'string', |
|
3912 ), |
|
3913 'size' => array( |
|
3914 'type' => 'number', |
|
3915 ), |
|
3916 'slug' => array( |
|
3917 'type' => 'string', |
|
3918 ), |
|
3919 ), |
|
3920 ), |
|
3921 ), |
|
3922 ), |
|
3923 ) |
|
3924 ); |
|
3925 register_theme_feature( |
|
3926 'editor-gradient-presets', |
|
3927 array( |
|
3928 'type' => 'array', |
|
3929 'description' => __( 'Custom gradient presets if defined by the theme.' ), |
|
3930 'show_in_rest' => array( |
|
3931 'schema' => array( |
|
3932 'items' => array( |
|
3933 'type' => 'object', |
|
3934 'properties' => array( |
|
3935 'name' => array( |
|
3936 'type' => 'string', |
|
3937 ), |
|
3938 'gradient' => array( |
|
3939 'type' => 'string', |
|
3940 ), |
|
3941 'slug' => array( |
|
3942 'type' => 'string', |
|
3943 ), |
|
3944 ), |
|
3945 ), |
|
3946 ), |
|
3947 ), |
|
3948 ) |
|
3949 ); |
|
3950 register_theme_feature( |
|
3951 'editor-styles', |
|
3952 array( |
|
3953 'description' => __( 'Whether theme opts in to the editor styles CSS wrapper.' ), |
|
3954 'show_in_rest' => true, |
|
3955 ) |
|
3956 ); |
|
3957 register_theme_feature( |
|
3958 'html5', |
|
3959 array( |
|
3960 'type' => 'array', |
|
3961 'description' => __( 'Allows use of HTML5 markup for search forms, comment forms, comment lists, gallery, and caption.' ), |
|
3962 'show_in_rest' => array( |
|
3963 'schema' => array( |
|
3964 'items' => array( |
|
3965 'type' => 'string', |
|
3966 'enum' => array( |
|
3967 'search-form', |
|
3968 'comment-form', |
|
3969 'comment-list', |
|
3970 'gallery', |
|
3971 'caption', |
|
3972 'script', |
|
3973 'style', |
|
3974 ), |
|
3975 ), |
|
3976 ), |
|
3977 ), |
|
3978 ) |
|
3979 ); |
|
3980 register_theme_feature( |
|
3981 'post-formats', |
|
3982 array( |
|
3983 'type' => 'array', |
|
3984 'description' => __( 'Post formats supported.' ), |
|
3985 'show_in_rest' => array( |
|
3986 'name' => 'formats', |
|
3987 'schema' => array( |
|
3988 'items' => array( |
|
3989 'type' => 'string', |
|
3990 'enum' => get_post_format_slugs(), |
|
3991 ), |
|
3992 'default' => array( 'standard' ), |
|
3993 ), |
|
3994 'prepare_callback' => static function ( $formats ) { |
|
3995 $formats = is_array( $formats ) ? array_values( $formats[0] ) : array(); |
|
3996 $formats = array_merge( array( 'standard' ), $formats ); |
|
3997 |
|
3998 return $formats; |
|
3999 }, |
|
4000 ), |
|
4001 ) |
|
4002 ); |
|
4003 register_theme_feature( |
|
4004 'post-thumbnails', |
|
4005 array( |
|
4006 'type' => 'array', |
|
4007 'description' => __( 'The post types that support thumbnails or true if all post types are supported.' ), |
|
4008 'show_in_rest' => array( |
|
4009 'type' => array( 'boolean', 'array' ), |
|
4010 'schema' => array( |
|
4011 'items' => array( |
|
4012 'type' => 'string', |
|
4013 ), |
|
4014 ), |
|
4015 ), |
|
4016 ) |
|
4017 ); |
|
4018 register_theme_feature( |
|
4019 'responsive-embeds', |
|
4020 array( |
|
4021 'description' => __( 'Whether the theme supports responsive embedded content.' ), |
|
4022 'show_in_rest' => true, |
|
4023 ) |
|
4024 ); |
|
4025 register_theme_feature( |
|
4026 'title-tag', |
|
4027 array( |
|
4028 'description' => __( 'Whether the theme can manage the document title tag.' ), |
|
4029 'show_in_rest' => true, |
|
4030 ) |
|
4031 ); |
|
4032 register_theme_feature( |
|
4033 'wp-block-styles', |
|
4034 array( |
|
4035 'description' => __( 'Whether theme opts in to default WordPress block styles for viewing.' ), |
|
4036 'show_in_rest' => true, |
|
4037 ) |
|
4038 ); |
|
4039 } |