897 * Validates the theme requirements for WordPress version and PHP version. |
897 * Validates the theme requirements for WordPress version and PHP version. |
898 * |
898 * |
899 * Uses the information from `Requires at least` and `Requires PHP` headers |
899 * Uses the information from `Requires at least` and `Requires PHP` headers |
900 * defined in the theme's `style.css` file. |
900 * defined in the theme's `style.css` file. |
901 * |
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 |
902 * @since 5.5.0 |
|
903 * @since 5.8.0 Removed support for using `readme.txt` as a fallback. |
906 * |
904 * |
907 * @param string $stylesheet Directory name for the theme. |
905 * @param string $stylesheet Directory name for the theme. |
908 * @return true|WP_Error True if requirements are met, WP_Error on failure. |
906 * @return true|WP_Error True if requirements are met, WP_Error on failure. |
909 */ |
907 */ |
910 function validate_theme_requirements( $stylesheet ) { |
908 function validate_theme_requirements( $stylesheet ) { |
911 $theme = wp_get_theme( $stylesheet ); |
909 $theme = wp_get_theme( $stylesheet ); |
|
910 |
|
911 // If the theme is a Full Site Editing theme, check for the presence of the Gutenberg plugin. |
|
912 $theme_tags = $theme->get( 'Tags' ); |
|
913 |
|
914 if ( ! empty( $theme_tags ) && in_array( 'full-site-editing', $theme_tags, true ) && ! function_exists( 'gutenberg_is_fse_theme' ) ) { |
|
915 return new WP_Error( |
|
916 'theme_requires_gutenberg_plugin', |
|
917 sprintf( |
|
918 /* translators: %s: Theme name. */ |
|
919 _x( '<strong>Error:</strong> This theme (%s) uses Full Site Editing, which requires the Gutenberg plugin to be activated.', 'theme' ), |
|
920 $theme->display( 'Name' ) |
|
921 ) |
|
922 ); |
|
923 } |
912 |
924 |
913 $requirements = array( |
925 $requirements = array( |
914 'requires' => ! empty( $theme->get( 'RequiresWP' ) ) ? $theme->get( 'RequiresWP' ) : '', |
926 'requires' => ! empty( $theme->get( 'RequiresWP' ) ) ? $theme->get( 'RequiresWP' ) : '', |
915 'requires_php' => ! empty( $theme->get( 'RequiresPHP' ) ) ? $theme->get( 'RequiresPHP' ) : '', |
927 'requires_php' => ! empty( $theme->get( 'RequiresPHP' ) ) ? $theme->get( 'RequiresPHP' ) : '', |
916 ); |
928 ); |
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 |
929 |
933 $compatible_wp = is_wp_version_compatible( $requirements['requires'] ); |
930 $compatible_wp = is_wp_version_compatible( $requirements['requires'] ); |
934 $compatible_php = is_php_version_compatible( $requirements['requires_php'] ); |
931 $compatible_php = is_php_version_compatible( $requirements['requires_php'] ); |
935 |
932 |
936 if ( ! $compatible_wp && ! $compatible_php ) { |
933 if ( ! $compatible_wp && ! $compatible_php ) { |
1022 } |
1019 } |
1023 |
1020 |
1024 if ( is_string( $default ) ) { |
1021 if ( is_string( $default ) ) { |
1025 // Only run the replacement if an sprintf() string format pattern was found. |
1022 // Only run the replacement if an sprintf() string format pattern was found. |
1026 if ( preg_match( '#(?<!%)%(?:\d+\$?)?s#', $default ) ) { |
1023 if ( preg_match( '#(?<!%)%(?:\d+\$?)?s#', $default ) ) { |
|
1024 // Remove a single trailing percent sign. |
|
1025 $default = preg_replace( '#(?<!%)%$#', '', $default ); |
1027 $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1026 $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ); |
1028 } |
1027 } |
1029 } |
1028 } |
1030 |
1029 |
1031 /** This filter is documented in wp-includes/theme.php */ |
1030 /** This filter is documented in wp-includes/theme.php */ |
1034 |
1033 |
1035 /** |
1034 /** |
1036 * Updates theme modification value for the current theme. |
1035 * Updates theme modification value for the current theme. |
1037 * |
1036 * |
1038 * @since 2.1.0 |
1037 * @since 2.1.0 |
|
1038 * @since 5.6.0 A return value was added. |
1039 * |
1039 * |
1040 * @param string $name Theme modification name. |
1040 * @param string $name Theme modification name. |
1041 * @param mixed $value Theme modification value. |
1041 * @param mixed $value Theme modification value. |
|
1042 * @return bool True if the value was updated, false otherwise. |
1042 */ |
1043 */ |
1043 function set_theme_mod( $name, $value ) { |
1044 function set_theme_mod( $name, $value ) { |
1044 $mods = get_theme_mods(); |
1045 $mods = get_theme_mods(); |
1045 $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; |
1046 $old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false; |
1046 |
1047 |
1057 * @param string $old_value The current value of the theme modification. |
1058 * @param string $old_value The current value of the theme modification. |
1058 */ |
1059 */ |
1059 $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); |
1060 $mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value ); |
1060 |
1061 |
1061 $theme = get_option( 'stylesheet' ); |
1062 $theme = get_option( 'stylesheet' ); |
1062 update_option( "theme_mods_$theme", $mods ); |
1063 |
|
1064 return update_option( "theme_mods_$theme", $mods ); |
1063 } |
1065 } |
1064 |
1066 |
1065 /** |
1067 /** |
1066 * Removes theme modification name from current theme list. |
1068 * Removes theme modification name from current theme list. |
1067 * |
1069 * |
2145 'widgets' => array( |
2150 'widgets' => array( |
2146 'text_business_info' => array( |
2151 'text_business_info' => array( |
2147 'text', |
2152 'text', |
2148 array( |
2153 array( |
2149 'title' => _x( 'Find Us', 'Theme starter content' ), |
2154 'title' => _x( 'Find Us', 'Theme starter content' ), |
2150 'text' => join( |
2155 'text' => implode( |
2151 '', |
2156 '', |
2152 array( |
2157 array( |
2153 '<strong>' . _x( 'Address', 'Theme starter content' ) . "</strong>\n", |
2158 '<strong>' . _x( 'Address', 'Theme starter content' ) . "</strong>\n", |
2154 _x( '123 Main Street', 'Theme starter content' ) . "\n" . _x( 'New York, NY 10001', 'Theme starter content' ) . "\n\n", |
2159 _x( '123 Main Street', 'Theme starter content' ) . "\n" . _x( 'New York, NY 10001', 'Theme starter content' ) . "\n\n", |
2155 '<strong>' . _x( 'Hours', 'Theme starter content' ) . "</strong>\n", |
2160 '<strong>' . _x( 'Hours', 'Theme starter content' ) . "</strong>\n", |
2471 * @since 5.3.0 The `html5` feature now also accepts 'script' and 'style'. |
2476 * @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 |
2477 * @since 5.3.0 Formalized the existing and already documented `...$args` parameter |
2473 * by adding it to the function signature. |
2478 * by adding it to the function signature. |
2474 * @since 5.5.0 The `core-block-patterns` feature was added and is enabled by default. |
2479 * @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'. |
2480 * @since 5.5.0 The `custom-logo` feature now also accepts 'unlink-homepage-logo'. |
|
2481 * @since 5.6.0 The `post-formats` feature warns if no array is passed. |
|
2482 * @since 5.8.0 The `widgets-block-editor` feature enables the Widgets block editor. |
2476 * |
2483 * |
2477 * @global array $_wp_theme_features |
2484 * @global array $_wp_theme_features |
2478 * |
2485 * |
2479 * @param string $feature The feature being added. Likely core values include 'post-formats', 'post-thumbnails', |
2486 * @param string $feature The feature being added. Likely core values include: |
2480 * 'custom-header', 'custom-background', 'custom-logo', 'menus', 'automatic-feed-links', |
2487 * - 'admin-bar' |
2481 * 'html5', 'title-tag', 'customize-selective-refresh-widgets', 'starter-content', |
2488 * - 'align-wide' |
2482 * 'responsive-embeds', 'align-wide', 'dark-editor-style', 'disable-custom-colors', |
2489 * - 'automatic-feed-links' |
2483 * 'disable-custom-font-sizes', 'editor-color-palette', 'editor-font-sizes', |
2490 * - 'core-block-patterns' |
2484 * 'editor-styles', 'wp-block-styles', and 'core-block-patterns'. |
2491 * - 'custom-background' |
|
2492 * - 'custom-header' |
|
2493 * - 'custom-line-height' |
|
2494 * - 'custom-logo' |
|
2495 * - 'customize-selective-refresh-widgets' |
|
2496 * - 'custom-spacing' |
|
2497 * - 'custom-units' |
|
2498 * - 'dark-editor-style' |
|
2499 * - 'disable-custom-colors' |
|
2500 * - 'disable-custom-font-sizes' |
|
2501 * - 'editor-color-palette' |
|
2502 * - 'editor-gradient-presets' |
|
2503 * - 'editor-font-sizes' |
|
2504 * - 'editor-styles' |
|
2505 * - 'featured-content' |
|
2506 * - 'html5' |
|
2507 * - 'menus' |
|
2508 * - 'post-formats' |
|
2509 * - 'post-thumbnails' |
|
2510 * - 'responsive-embeds' |
|
2511 * - 'starter-content' |
|
2512 * - 'title-tag' |
|
2513 * - 'wp-block-styles' |
|
2514 * - 'widgets' |
|
2515 * - 'widgets-block-editor' |
2485 * @param mixed ...$args Optional extra arguments to pass along with certain features. |
2516 * @param mixed ...$args Optional extra arguments to pass along with certain features. |
2486 * @return void|bool False on failure, void otherwise. |
2517 * @return void|false Void on success, false on failure. |
2487 */ |
2518 */ |
2488 function add_theme_support( $feature, ...$args ) { |
2519 function add_theme_support( $feature, ...$args ) { |
2489 global $_wp_theme_features; |
2520 global $_wp_theme_features; |
2490 |
2521 |
2491 if ( ! $args ) { |
2522 if ( ! $args ) { |
2513 if ( isset( $args[0] ) && is_array( $args[0] ) ) { |
2544 if ( isset( $args[0] ) && is_array( $args[0] ) ) { |
2514 $post_formats = get_post_format_slugs(); |
2545 $post_formats = get_post_format_slugs(); |
2515 unset( $post_formats['standard'] ); |
2546 unset( $post_formats['standard'] ); |
2516 |
2547 |
2517 $args[0] = array_intersect( $args[0], array_keys( $post_formats ) ); |
2548 $args[0] = array_intersect( $args[0], array_keys( $post_formats ) ); |
|
2549 } else { |
|
2550 _doing_it_wrong( "add_theme_support( 'post-formats' )", __( 'You need to pass an array of post formats.' ), '5.6.0' ); |
|
2551 return false; |
2518 } |
2552 } |
2519 break; |
2553 break; |
2520 |
2554 |
2521 case 'html5': |
2555 case 'html5': |
2522 // You can't just pass 'html5', you need to pass an array of types. |
2556 // You can't just pass 'html5', you need to pass an array of types. |