add_theme_support( string $feature, mixed $args ): void|false
Registers theme support for a given feature.
Contents
Description
Must be called in the theme’s functions.php file to work.
If attached to a hook, it must be ‘after_setup_theme’.
The ‘init’ hook may be too late for some features.
Example usage:
add_theme_support( 'title-tag' );
add_theme_support( 'custom-logo', array(
'height' => 480,
'width' => 720,
) );
Parameters
-
$feature
string Required -
The feature being added. Likely core values include:
'admin-bar'
'align-wide'
'automatic-feed-links'
'core-block-patterns'
'custom-background'
'custom-header'
'custom-line-height'
'custom-logo'
'customize-selective-refresh-widgets'
'custom-spacing'
'custom-units'
'dark-editor-style'
'disable-custom-colors'
'disable-custom-font-sizes'
'editor-color-palette'
'editor-gradient-presets'
'editor-font-sizes'
'editor-styles'
'featured-content'
'html5'
'menus'
'post-formats'
'post-thumbnails'
'responsive-embeds'
'starter-content'
'title-tag'
'wp-block-styles'
'widgets'
'widgets-block-editor'
-
$args
mixed Optional -
Optional extra arguments to pass along with certain features.
Return
void|false Void on success, false on failure.
More Information
Features
Post Formats
add_theme_support( 'post-formats' )
will override the formats as defined by the parent theme, not add to it.
To enable the specific formats (see supported formats at Post Formats), use:
add_theme_support( 'post-formats', array( 'aside', 'gallery' ) );
To check if there is a ‘quote’ post format assigned to the post, use has_post_format() :
// In your theme single.php, page.php or custom post type
if ( has_post_format( 'quote' ) ) {
echo 'This is a quote.';
}
Post Thumbnails
$args
, with an array of the Post Types for which you want to enable this feature.
add_theme_support( 'post-thumbnails' );
add_theme_support( 'post-thumbnails', array( 'post' ) ); // Posts only
add_theme_support( 'post-thumbnails', array( 'page' ) ); // Pages only
add_theme_support( 'post-thumbnails', array( 'post', 'movie' ) ); // Posts and Movies
This feature must be called before the ‘init’ hook is fired. That means it needs to be placed directly into functions.php or within a function attached to the ‘after_setup_theme’ hook. For custom post types, you can also add post thumbnails using the register_post_type() function as well.
To display thumbnails in themes index.php or single.php or custom templates, use:
the_post_thumbnail();
To check if there is a post thumbnail assigned to the post before displaying it, use:
if ( has_post_thumbnail() ) {
the_post_thumbnail();
}
Custom Background
add_theme_support( 'custom-background' );
Note that you can add default arguments using:
$defaults = array(
'default-image' => '',
'default-preset' => 'default', // 'default', 'fill', 'fit', 'repeat', 'custom'
'default-position-x' => 'left', // 'left', 'center', 'right'
'default-position-y' => 'top', // 'top', 'center', 'bottom'
'default-size' => 'auto', // 'auto', 'contain', 'cover'
'default-repeat' => 'repeat', // 'repeat-x', 'repeat-y', 'repeat', 'no-repeat'
'default-attachment' => 'scroll', // 'scroll', 'fixed'
'default-color' => '',
'wp-head-callback' => '_custom_background_cb',
'admin-head-callback' => '',
'admin-preview-callback' => '',
);
add_theme_support( 'custom-background', $defaults );
Custom Header
add_theme_support( 'custom-header' );
Note that you can add default arguments using:
$defaults = array(
'default-image' => '',
'random-default' => false,
'width' => 0,
'height' => 0,
'flex-height' => false,
'flex-width' => false,
'default-text-color' => '',
'header-text' => true,
'uploads' => true,
'wp-head-callback' => '',
'admin-head-callback' => '',
'admin-preview-callback' => '',
'video' => false,
'video-active-callback' => 'is_front_page',
);
add_theme_support( 'custom-header', $defaults );
Custom Logo
add_theme_support( 'custom-logo' );
Note that you can add default arguments using:
add_theme_support( 'custom-logo', array(
'height' => 100,
'width' => 400,
'flex-height' => true,
'flex-width' => true,
'header-text' => array( 'site-title', 'site-description' ),
'unlink-homepage-logo' => true,
) );
Feed Links
add_theme_support( 'automatic-feed-links' );
HTML5
add_theme_support( 'html5', array( 'comment-list', 'comment-form', 'search-form', 'gallery', 'caption', 'style', 'script' ) );
Title Tag
add_theme_support( 'title-tag' );
Customize Selective Refresh Widgets
add_theme_support( 'customize-selective-refresh-widgets' );
Multisite
jpg jpeg png gif mp3 mov avi wmv midi mid pdf
.
Other Notes
sidebars
: Use register_sidebar() or register_sidebars() instead.menus
: Use register_nav_menu() or register_nav_menus() instead.editor-style
: Use add_editor_style() instead.
Source
File: wp-includes/theme.php
.
View all references
function add_theme_support( $feature, ...$args ) {
global $_wp_theme_features;
if ( ! $args ) {
$args = true;
}
switch ( $feature ) {
case 'post-thumbnails':
// All post types are already supported.
if ( true === get_theme_support( 'post-thumbnails' ) ) {
return;
}
/*
* Merge post types with any that already declared their support
* for post thumbnails.
*/
if ( isset( $args[0] ) && is_array( $args[0] ) && isset( $_wp_theme_features['post-thumbnails'] ) ) {
$args[0] = array_unique( array_merge( $_wp_theme_features['post-thumbnails'][0], $args[0] ) );
}
break;
case 'post-formats':
if ( isset( $args[0] ) && is_array( $args[0] ) ) {
$post_formats = get_post_format_slugs();
unset( $post_formats['standard'] );
$args[0] = array_intersect( $args[0], array_keys( $post_formats ) );
} else {
_doing_it_wrong(
"add_theme_support( 'post-formats' )",
__( 'You need to pass an array of post formats.' ),
'5.6.0'
);
return false;
}
break;
case 'html5':
// You can't just pass 'html5', you need to pass an array of types.
if ( empty( $args[0] ) || ! is_array( $args[0] ) ) {
_doing_it_wrong(
"add_theme_support( 'html5' )",
__( 'You need to pass an array of types.' ),
'3.6.1'
);
if ( ! empty( $args[0] ) && ! is_array( $args[0] ) ) {
return false;
}
// Build an array of types for back-compat.
$args = array( 0 => array( 'comment-list', 'comment-form', 'search-form' ) );
}
// Calling 'html5' again merges, rather than overwrites.
if ( isset( $_wp_theme_features['html5'] ) ) {
$args[0] = array_merge( $_wp_theme_features['html5'][0], $args[0] );
}
break;
case 'custom-logo':
if ( true === $args ) {
$args = array( 0 => array() );
}
$defaults = array(
'width' => null,
'height' => null,
'flex-width' => false,
'flex-height' => false,
'header-text' => '',
'unlink-homepage-logo' => false,
);
$args[0] = wp_parse_args( array_intersect_key( $args[0], $defaults ), $defaults );
// Allow full flexibility if no size is specified.
if ( is_null( $args[0]['width'] ) && is_null( $args[0]['height'] ) ) {
$args[0]['flex-width'] = true;
$args[0]['flex-height'] = true;
}
break;
case 'custom-header-uploads':
return add_theme_support( 'custom-header', array( 'uploads' => true ) );
case 'custom-header':
if ( true === $args ) {
$args = array( 0 => array() );
}
$defaults = array(
'default-image' => '',
'random-default' => false,
'width' => 0,
'height' => 0,
'flex-height' => false,
'flex-width' => false,
'default-text-color' => '',
'header-text' => true,
'uploads' => true,
'wp-head-callback' => '',
'admin-head-callback' => '',
'admin-preview-callback' => '',
'video' => false,
'video-active-callback' => 'is_front_page',
);
$jit = isset( $args[0]['__jit'] );
unset( $args[0]['__jit'] );
/*
* Merge in data from previous add_theme_support() calls.
* The first value registered wins. (A child theme is set up first.)
*/
if ( isset( $_wp_theme_features['custom-header'] ) ) {
$args[0] = wp_parse_args( $_wp_theme_features['custom-header'][0], $args[0] );
}
/*
* Load in the defaults at the end, as we need to insure first one wins.
* This will cause all constants to be defined, as each arg will then be set to the default.
*/
if ( $jit ) {
$args[0] = wp_parse_args( $args[0], $defaults );
}
/*
* If a constant was defined, use that value. Otherwise, define the constant to ensure
* the constant is always accurate (and is not defined later, overriding our value).
* As stated above, the first value wins.
* Once we get to wp_loaded (just-in-time), define any constants we haven't already.
* Constants are lame. Don't reference them. This is just for backward compatibility.
*/
if ( defined( 'NO_HEADER_TEXT' ) ) {
$args[0]['header-text'] = ! NO_HEADER_TEXT;
} elseif ( isset( $args[0]['header-text'] ) ) {
define( 'NO_HEADER_TEXT', empty( $args[0]['header-text'] ) );
}
if ( defined( 'HEADER_IMAGE_WIDTH' ) ) {
$args[0]['width'] = (int) HEADER_IMAGE_WIDTH;
} elseif ( isset( $args[0]['width'] ) ) {
define( 'HEADER_IMAGE_WIDTH', (int) $args[0]['width'] );
}
if ( defined( 'HEADER_IMAGE_HEIGHT' ) ) {
$args[0]['height'] = (int) HEADER_IMAGE_HEIGHT;
} elseif ( isset( $args[0]['height'] ) ) {
define( 'HEADER_IMAGE_HEIGHT', (int) $args[0]['height'] );
}
if ( defined( 'HEADER_TEXTCOLOR' ) ) {
$args[0]['default-text-color'] = HEADER_TEXTCOLOR;
} elseif ( isset( $args[0]['default-text-color'] ) ) {
define( 'HEADER_TEXTCOLOR', $args[0]['default-text-color'] );
}
if ( defined( 'HEADER_IMAGE' ) ) {
$args[0]['default-image'] = HEADER_IMAGE;
} elseif ( isset( $args[0]['default-image'] ) ) {
define( 'HEADER_IMAGE', $args[0]['default-image'] );
}
if ( $jit && ! empty( $args[0]['default-image'] ) ) {
$args[0]['random-default'] = false;
}
/*
* If headers are supported, and we still don't have a defined width or height,
* we have implicit flex sizes.
*/
if ( $jit ) {
if ( empty( $args[0]['width'] ) && empty( $args[0]['flex-width'] ) ) {
$args[0]['flex-width'] = true;
}
if ( empty( $args[0]['height'] ) && empty( $args[0]['flex-height'] ) ) {
$args[0]['flex-height'] = true;
}
}
break;
case 'custom-background':
if ( true === $args ) {
$args = array( 0 => array() );
}
$defaults = array(
'default-image' => '',
'default-preset' => 'default',
'default-position-x' => 'left',
'default-position-y' => 'top',
'default-size' => 'auto',
'default-repeat' => 'repeat',
'default-attachment' => 'scroll',
'default-color' => '',
'wp-head-callback' => '_custom_background_cb',
'admin-head-callback' => '',
'admin-preview-callback' => '',
);
$jit = isset( $args[0]['__jit'] );
unset( $args[0]['__jit'] );
// Merge in data from previous add_theme_support() calls. The first value registered wins.
if ( isset( $_wp_theme_features['custom-background'] ) ) {
$args[0] = wp_parse_args( $_wp_theme_features['custom-background'][0], $args[0] );
}
if ( $jit ) {
$args[0] = wp_parse_args( $args[0], $defaults );
}
if ( defined( 'BACKGROUND_COLOR' ) ) {
$args[0]['default-color'] = BACKGROUND_COLOR;
} elseif ( isset( $args[0]['default-color'] ) || $jit ) {
define( 'BACKGROUND_COLOR', $args[0]['default-color'] );
}
if ( defined( 'BACKGROUND_IMAGE' ) ) {
$args[0]['default-image'] = BACKGROUND_IMAGE;
} elseif ( isset( $args[0]['default-image'] ) || $jit ) {
define( 'BACKGROUND_IMAGE', $args[0]['default-image'] );
}
break;
// Ensure that 'title-tag' is accessible in the admin.
case 'title-tag':
// Can be called in functions.php but must happen before wp_loaded, i.e. not in header.php.
if ( did_action( 'wp_loaded' ) ) {
_doing_it_wrong(
"add_theme_support( 'title-tag' )",
sprintf(
/* translators: 1: title-tag, 2: wp_loaded */
__( 'Theme support for %1$s should be registered before the %2$s hook.' ),
'<code>title-tag</code>',
'<code>wp_loaded</code>'
),
'4.1.0'
);
return false;
}
}
$_wp_theme_features[ $feature ] = $args;
}
Changelog
Version | Description |
---|---|
6.0.0 | The html5 feature warns if no array is passed as the second parameter. |
5.8.0 | The widgets-block-editor feature enables the Widgets block editor. |
5.6.0 | The post-formats feature warns if no array is passed as the second parameter. |
5.5.0 | The custom-logo feature now also accepts 'unlink-homepage-logo' . |
5.3.0 | Formalized the existing and already documented ...$args parameter by adding it to the function signature. |
5.0.0 | The responsive-embeds , align-wide , dark-editor-style , disable-custom-colors , disable-custom-font-sizes , editor-color-palette , editor-font-sizes , editor-styles , and wp-block-styles features were added. |
4.7.0 | The starter-content feature was added. |
4.5.0 | The customize-selective-refresh-widgets feature was added. |
4.1.0 | The title-tag feature was added. |
3.9.0 | The html5 feature now also accepts 'gallery' and 'caption' . |
3.6.1 | The html5 feature requires an array of types to be passed. Defaults to 'comment-list' , 'comment-form' , 'search-form' for backward compatibility. |
3.6.0 | The html5 feature was added. |
3.4.0 | The custom-header-uploads feature was deprecated. |
2.9.0 | Introduced. |
User Contributed Notes
You must log in before being able to contribute a note or feedback.
Feedback:
There needs to be a section for starter content.
This page has good explanation https://make.wordpress.org/core/2016/11/30/starter-content-for-themes-in-4-7/
and this function shows all the default values: https://developer.wordpress.org/reference/functions/get_theme_starter_content/
Enabling theme support for align full and align wide option for the block editor, use
add_theme_support( 'align-wide' );
From WP 5.3,
add_theme_support('html5', ['script', 'style']);
removestype="text/javascript"
and type=”text/css” from enqueued scripts and styles.See https://make.wordpress.org/core/2019/10/15/miscellaneous-developer-focused-changes-in-5-3/ – HTML5 Supports Argument for Script and Style Tags
The following features are enabled by default in block themes from version 5.9 onwards:
post-thumbnails
responsive-embeds
editor-styles
html5
automatic-feed-links
See #35593 | (source)
To determine if the theme support exists (and retrieve it’s arguments), use
get_theme_support( $feature )
https://developer.wordpress.org/reference/functions/get_theme_support/
The Changelog missing the row:
“The html5 feature now also accepts ‘script and ‘style’.”
Don’t know what version it was added in, but its there in 5.3.1 atleast.
Exemple of use:
https://github.com/WordPress/WordPress/blob/48692b65241fcbadcd686c3f66696e16883a0e83/wp-includes/theme.php#L708
https://github.com/WordPress/WordPress/blob/48692b65241fcbadcd686c3f66696e16883a0e83/wp-includes/theme.php#L3233
Commit:
https://github.com/WordPress/WordPress/commit/252628652e7706cabb3913f4aa57218fa5012e4b
Note that you have to individually call each of these; including multiple ones as an array
add_theme_support( array( 'editor-styles', 'align-wide' ) )
Instead, you must call them individually:
Declare support for navigation widgets markup.
“Theme developers are highly encouraged to utilize this improvement in their themes. This new theme support feature is an easy way to improve semantics and accessibility in all of the sites using your theme.”
“default-color” for custom background doesn’t work
Solution is to define your own stylesheet class and add the CSS class to the
body
tag.Top ↑
Feedback
The
default-color
argument doesn’t actually set the background color: the theme has to implement the default color using CSS. — By crstauf —Declare support for Block Styles.
These will enable the support for default Gutenberg block styles in the theme.
Top ↑
Feedback
View Docs — By tresorama —
deactivate new block editor Widget and active old editor Widget
If you enable
'responsive-embeds'
, these are responsive classes you can use (.wp-embed-aspect-21-9
) etc. on embedded block (like e.g. youtube):Starter Content #
Defines and registers starter content to showcase themes on new sites.
For full examples of each option, you can reference the Twenty Seventeen theme’s
functions.php
:https://github.com/xwp/wordpress-develop/blob/master/src/wp-content/themes/twentyseventeen/functions.php#L117