: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Retrieves all theme modifications.
* @since 5.9.0 The return value is always an array.
* @return array Theme modifications.
function get_theme_mods() {
$theme_slug = get_option( 'stylesheet' );
$mods = get_option( "theme_mods_$theme_slug" );
$theme_name = get_option( 'current_theme' );
if ( false === $theme_name ) {
$theme_name = wp_get_theme()->get( 'Name' );
$mods = get_option( "mods_$theme_name" ); // Deprecated location.
if ( is_admin() && false !== $mods ) {
update_option( "theme_mods_$theme_slug", $mods );
delete_option( "mods_$theme_name" );
if ( ! is_array( $mods ) ) {
* Retrieves theme modification value for the active theme.
* If the modification name does not exist and `$default_value` is a string, then the
* default will be passed through the {@link https://www.php.net/sprintf sprintf()}
* PHP function with the template directory URI as the first value and the
* stylesheet directory URI as the second value.
* @param string $name Theme modification name.
* @param mixed $default_value Optional. Theme modification default value. Default false.
* @return mixed Theme modification value.
function get_theme_mod( $name, $default_value = false ) {
$mods = get_theme_mods();
if ( isset( $mods[ $name ] ) ) {
* Filters the theme modification, or 'theme_mod', value.
* The dynamic portion of the hook name, `$name`, refers to the key name
* of the modification array. For example, 'header_textcolor', 'header_image',
* and so on depending on the theme options.
* @param mixed $current_mod The value of the active theme modification.
return apply_filters( "theme_mod_{$name}", $mods[ $name ] );
if ( is_string( $default_value ) ) {
// Only run the replacement if an sprintf() string format pattern was found.
if ( preg_match( '#(?<!%)%(?:\d+\$?)?s#', $default_value ) ) {
// Remove a single trailing percent sign.
$default_value = preg_replace( '#(?<!%)%$#', '', $default_value );
$default_value = sprintf( $default_value, get_template_directory_uri(), get_stylesheet_directory_uri() );
/** This filter is documented in wp-includes/theme.php */
return apply_filters( "theme_mod_{$name}", $default_value );
* Updates theme modification value for the active theme.
* @since 5.6.0 A return value was added.
* @param string $name Theme modification name.
* @param mixed $value Theme modification value.
* @return bool True if the value was updated, false otherwise.
function set_theme_mod( $name, $value ) {
$mods = get_theme_mods();
$old_value = isset( $mods[ $name ] ) ? $mods[ $name ] : false;
* Filters the theme modification, or 'theme_mod', value on save.
* The dynamic portion of the hook name, `$name`, refers to the key name
* of the modification array. For example, 'header_textcolor', 'header_image',
* and so on depending on the theme options.
* @param mixed $value The new value of the theme modification.
* @param mixed $old_value The current value of the theme modification.
$mods[ $name ] = apply_filters( "pre_set_theme_mod_{$name}", $value, $old_value );
$theme = get_option( 'stylesheet' );
return update_option( "theme_mods_$theme", $mods );
* Removes theme modification name from active theme list.
* If removing the name also removes all elements, then the entire option
* @param string $name Theme modification name.
function remove_theme_mod( $name ) {
$mods = get_theme_mods();
if ( ! isset( $mods[ $name ] ) ) {
$theme = get_option( 'stylesheet' );
update_option( "theme_mods_$theme", $mods );
* Removes theme modifications option for the active theme.
function remove_theme_mods() {
delete_option( 'theme_mods_' . get_option( 'stylesheet' ) );
$theme_name = get_option( 'current_theme' );
if ( false === $theme_name ) {
$theme_name = wp_get_theme()->get( 'Name' );
delete_option( 'mods_' . $theme_name );
* Retrieves the custom header text color in 3- or 6-digit hexadecimal form.
* @return string Header text color in 3- or 6-digit hexadecimal form (minus the hash symbol).
function get_header_textcolor() {
return get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) );
* Displays the custom header text color in 3- or 6-digit hexadecimal form (minus the hash symbol).
function header_textcolor() {
echo get_header_textcolor();
* Whether to display the header text.
function display_header_text() {
if ( ! current_theme_supports( 'custom-header', 'header-text' ) ) {
$text_color = get_theme_mod( 'header_textcolor', get_theme_support( 'custom-header', 'default-text-color' ) );
return 'blank' !== $text_color;
* Checks whether a header image is set or not.
* @see get_header_image()
* @return bool Whether a header image is set or not.
function has_header_image() {
return (bool) get_header_image();
* Retrieves header image for custom header.
function get_header_image() {
$url = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) );
if ( 'remove-header' === $url ) {
if ( is_random_header_image() ) {
$url = get_random_header_image();
* Filters the header image URL.
* @param string $url Header image URL.
$url = apply_filters( 'get_header_image', $url );
if ( ! is_string( $url ) ) {
return sanitize_url( set_url_scheme( $url ) );
* Creates image tag markup for a custom header image.
* @param array $attr Optional. Additional attributes for the image tag. Can be used
* to override the default attributes. Default empty.
* @return string HTML image element markup or empty string on failure.
function get_header_image_tag( $attr = array() ) {
$header = get_custom_header();
$header->url = get_header_image();
$width = absint( $header->width );
$height = absint( $header->height );
// Use alternative text assigned to the image, if available. Otherwise, leave it empty.
if ( ! empty( $header->attachment_id ) ) {
$image_alt = get_post_meta( $header->attachment_id, '_wp_attachment_image_alt', true );
if ( is_string( $image_alt ) ) {
// Generate 'srcset' and 'sizes' if not already present.
if ( empty( $attr['srcset'] ) && ! empty( $header->attachment_id ) ) {
$image_meta = get_post_meta( $header->attachment_id, '_wp_attachment_metadata', true );
$size_array = array( $width, $height );
if ( is_array( $image_meta ) ) {
$srcset = wp_calculate_image_srcset( $size_array, $header->url, $image_meta, $header->attachment_id );
if ( ! empty( $attr['sizes'] ) ) {
$sizes = wp_calculate_image_sizes( $size_array, $header->url, $image_meta, $header->attachment_id );
if ( $srcset && $sizes ) {
$attr['srcset'] = $srcset;
wp_get_loading_optimization_attributes( 'img', $attr, 'get_header_image_tag' )
* If the default value of `lazy` for the `loading` attribute is overridden
* to omit the attribute for this image, ensure it is not included.
if ( isset( $attr['loading'] ) && ! $attr['loading'] ) {
unset( $attr['loading'] );
// If the `fetchpriority` attribute is overridden and set to false or an empty string.
if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) {
unset( $attr['fetchpriority'] );
// If the `decoding` attribute is overridden and set to false or an empty string.
if ( isset( $attr['decoding'] ) && ! $attr['decoding'] ) {
unset( $attr['decoding'] );
* Filters the list of header image attributes.
* @param array $attr Array of the attributes for the image tag.
* @param object $header The custom header object returned by 'get_custom_header()'.
$attr = apply_filters( 'get_header_image_tag_attributes', $attr, $header );
$attr = array_map( 'esc_attr', $attr );
foreach ( $attr as $name => $value ) {
$html .= ' ' . $name . '="' . $value . '"';
* Filters the markup of header images.
* @param string $html The HTML image tag markup being filtered.
* @param object $header The custom header object returned by 'get_custom_header()'.
* @param array $attr Array of the attributes for the image tag.
return apply_filters( 'get_header_image_tag', $html, $header, $attr );
* Displays the image markup for a custom header image.
* @param array $attr Optional. Attributes for the image markup. Default empty.
function the_header_image_tag( $attr = array() ) {
echo get_header_image_tag( $attr );
* Gets random header image data from registered images in theme.
* @global array $_wp_default_headers
function _get_random_header_data() {
global $_wp_default_headers;
static $_wp_random_header = null;
if ( empty( $_wp_random_header ) ) {
$header_image_mod = get_theme_mod( 'header_image', '' );
if ( 'random-uploaded-image' === $header_image_mod ) {
$headers = get_uploaded_header_images();
} elseif ( ! empty( $_wp_default_headers ) ) {
if ( 'random-default-image' === $header_image_mod ) {
$headers = $_wp_default_headers;
if ( current_theme_supports( 'custom-header', 'random-default' ) ) {
$headers = $_wp_default_headers;
if ( empty( $headers ) ) {
$_wp_random_header = (object) $headers[ array_rand( $headers ) ];
$_wp_random_header->url = sprintf(
get_template_directory_uri(),
get_stylesheet_directory_uri()
$_wp_random_header->thumbnail_url = sprintf(
$_wp_random_header->thumbnail_url,
get_template_directory_uri(),
get_stylesheet_directory_uri()
return $_wp_random_header;
* Gets random header image URL from registered images in theme.
* @return string Path to header image.
function get_random_header_image() {
$random_image = _get_random_header_data();
if ( empty( $random_image->url ) ) {
return $random_image->url;
* Checks if random header image is in use.
* Always true if user expressly chooses the option in Appearance > Header.
* Also true if theme has multiple header images registered, no specific header image
* is chosen, and theme turns on random headers with add_theme_support().
* @param string $type The random pool to use. Possible values include 'any',
* 'default', 'uploaded'. Default 'any'.
function is_random_header_image( $type = 'any' ) {
$header_image_mod = get_theme_mod( 'header_image', get_theme_support( 'custom-header', 'default-image' ) );
if ( 'random-default-image' === $header_image_mod
|| 'random-uploaded-image' === $header_image_mod
|| ( empty( $header_image_mod ) && '' !== get_random_header_image() )
if ( "random-$type-image" === $header_image_mod ) {
} elseif ( 'default' === $type
&& empty( $header_image_mod ) && '' !== get_random_header_image()
* Displays header image URL.
function header_image() {
$image = get_header_image();
* Gets the header images uploaded for the active theme.
function get_uploaded_header_images() {