wppaste
WordPress

post_type_supports( string $post_type, string $feature ): bool

Since
3.0.0
Source
wp-includes/post.php:2381

Looks up whether a post type declares support for one feature, such as 'thumbnail' or 'comments', and returns a plain boolean. It reads the internal $_wp_post_type_features array that add_post_type_support() fills in, so the result depends on when in the request that support was registered. A false result also comes back for a post type that isn't registered at all, so it can't be used on its own to confirm the post type exists.

Checks a post type's support for a given feature.

Compatibility

WordPress
since 3.0.0
PHP
7.4–8.6-dev
  • 6.7.7
  • 6.8.8
  • 6.9.7
  • 7.0.4
  • 7.1.0

Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.

Parameters

$post_typestring
The post type being checked.
$featurestring
The feature being checked.

Return value

bool
Whether the post type supports the given feature.

Code examples

Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.

Check which features a post type supports

Loop over a handful of common feature names and print whether the built-in post and page post types support each one.

$features = array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments', 'page-attributes' );

foreach ( array( 'post', 'page' ) as $post_type ) {
	foreach ( $features as $feature ) {
		printf(
			'%s supports %s: %s<br>',
			esc_html( $post_type ),
			esc_html( $feature ),
			post_type_supports( $post_type, $feature ) ? 'yes' : 'no'
		);
	}
}

Show an admin notice only on post types that allow comments

Register an admin_notices callback that inspects the current screen's post type before deciding what to display.

add_action( 'admin_notices', function () {
	$screen = get_current_screen();

	if ( ! $screen || empty( $screen->post_type ) ) {
		return;
	}

	if ( post_type_supports( $screen->post_type, 'comments' ) ) {
		echo '<div class="notice notice-info"><p>' . esc_html( $screen->post_type ) . ' supports comments, so the Discussion panel is available here.</p></div>';
	} else {
		echo '<div class="notice notice-warning"><p>' . esc_html( $screen->post_type ) . ' does not support comments.</p></div>';
	}
} );

Open an edit screen for a post or page in wp-admin to see the notice fire.

Common problems and fixes · 3

Why does post_type_supports() return false right after I called add_post_type_support()?

Both functions share the same $_wp_post_type_features global, so the check only sees support that has already been registered by the time it runs. If add_post_type_support() runs on 'init' with a later priority, or on a hook that fires after the code doing the check, the feature simply isn't in the array yet. - Register support on 'init' at priority 0 or earlier than the code that checks it. - Confirm the post type itself is registered before adding support to it.

Why does post_type_supports() return true but the meta box I expect still isn't there?

The source only reports whether the feature key exists in $_wp_post_type_features, it says nothing about the UI. Some features have extra requirements on top of post type support: 'thumbnail' also needs add_theme_support( 'post-thumbnails' ), and box visibility can additionally depend on the current user's capabilities. - Check current_theme_supports( 'post-thumbnails' ) alongside post_type_supports() for featured images. - Verify the logged-in user's capabilities if a box is missing on the edit screen.

Can I use post_type_supports() to check if a custom post type is registered?

No. Because the function only does an isset() lookup on $_wp_post_type_features[ $post_type ][ $feature ], an unregistered post type name and a registered one that simply lacks that feature produce the exact same false result. Use post_type_exists() first if what you actually need is confirmation the post type exists.

Alternatives and related functions

add_post_type_support
When you need to register a feature for a post type rather than just read whether one is already registered.
get_all_post_type_supports
When you need the full list of features a post type supports instead of testing one feature at a time.
post_type_exists
When you need to confirm a post type is registered at all, since a false result here doesn't distinguish that case.
current_theme_supports
When the capability you're checking belongs to the active theme, such as post thumbnails or custom logos, rather than to a post type's own declared features.

Performance profile

How much work a call to post_type_supports() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.

Cost class
Trivial

Touches nothing outside its own arguments.

Scaling
Constant

No loop in the body: the same number of instructions runs whatever you pass in.

Instructions
6

Executed per call on PHP 8.5. The body compiles to 6.

Plugin surface
None

Nothing here hands control to plugin code.

Called by
45

45 places in core call this, so the cost is paid more often than your own code shows.

What one call costs · 1 distinct outcome

One number would be a lie: the work depends on which branch runs. These are every distinct cost post_type_supports() can have, taken from its control-flow graph on PHP 8.5.

WhenInstructionsCalls it makes
always6none

Across PHP versions

Compiles the same on PHP 7.4, 8.1, 8.2, 8.3, 8.4, 8.5 and 8.6-dev: 6 instructions, 6 executed per call, 0 branches. The work does not change between versions.

An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.

Used by · 45

Show all 45

Source code

function post_type_supports( $post_type, $feature ) {	global $_wp_post_type_features; 	return ( isset( $_wp_post_type_features[ $post_type ][ $feature ] ) );}

Changelog

Introduced in 3.0.0. Unchanged from 6.7.7 through 7.1.0.

  1. 6.7.7
  2. 6.8.8
  3. 6.9.7
  4. 7.0.4
  5. 7.1.0

Signature, return type and hooks compared across 5 parsed releases.

About this page

Parsed data
Generated from the wordpress-develop 7.1.0 tag, from src/wp-includes/post.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.
Corrections
Something wrong on this page? Report it and it gets fixed in the next regeneration.