In version 2.9, WordPress introduced one of my all-time favorite pieces of functionality for themes: theme-supported features. I haven’t seen many theme developers taking advantage of this useful feature. And, I haven’t really been putting this awesome functionality to the test until recently.
Theme-supported features allow theme developers to declare that their themes support specific features in WordPress with a quick, simple line of code. But, that’s not what really gets me excited about the functionality. Theme developers can also create custom features that users can turn on/off within child themes.
This system gives theme developers tons of flexibility by allowing them to make their themes more modular. It allows users to mix and match different elements and only use the features they want to use. This works so well that I’ve actually built the entire Hybrid Core framework off the concept.
WordPress theme-supported features
WordPress has several theme-supported features that themes may optionally use. Some people incorrectly think these are required features for themes to use. However, all theme-supported features are optional. That’s the entire purpose of this functionality in WordPress.
Currently, WordPress only has two features that you can add support for using the add_theme_support() function (described below):
automatic-feed-links: Automatically adds feed links to the<head>area of the site.post-thumbnails: Turns on the “featured image” feature.
WordPress also has other theme-supported features that it registers internally when one of the below functions is used. You should always use the given function if WordPress provides one for the feature rather than adding support manually.
editor-style: Registered when a theme uses add_editor_style().custom-background: Registered when a theme uses add_custom_background().custom-header-imageandcustom-header-uploads: Registered when a theme uses add_custom_image_header().menus: Registered when a theme uses register_nav_menus().widgets: Registered when a theme uses register_sidebar().
Adding theme support of a feature
<?php add_theme_support( $feature ); ?>
WordPress has a function called add_theme_support() that you would add within your theme’s functions.php file to declare that your theme supports a particular feature. It takes in a single parameter of $feature, which is a text string that represents the feature the theme should support.
So, let’s suppose you wanted to add support for the automatic feed links feature, you’d simply drop this code in your theme’s functions.php file:
<?php add_theme_support( 'automatic-feed-links' ); ?>
Removing theme support of a feature
<?php remove_theme_support( $feature ); ?>
This is where things get flexible. If a theme has previously registered support for a feature, you can use the remove_theme_support() function to remove support of it. There are two things that must happen though:
- The
$featurevariable must match what was used inadd_theme_support()exactly. - The
remove_theme_support()function must be called after theadd_theme_support()function was called.
In the previous section, we added support for the automatic feed links feature. Now, let’s remove it by adding this code to the theme’s functions.php file:
<?php remove_theme_support( 'automatic-feed-links' ); ?>
Checking if a feature is supported
<?php current_theme_supports( $feature ); ?>
The current_theme_supports() function allows you to check if a feature is supported by the theme. It’s a conditional tag that returns true if the feature is supported and false if not.
Let’s suppose you added support for post-thumbnails in your parent theme, but you want users to be able to remove this feature. You’ll need to check for support of this feature before calling the post thumbnail functions. Otherwise, users might get an error if they’ve removed support and you call the post thumbnail function.
The code snippet below checks for support of post-thumbnails. If they’re supported, it calls the the_post_thumbnail() function, which displays the thumbnail.
<?php if ( current_theme_supports( 'post-thumbnails' ) ) the_post_thumbnail(); ?>
Now, users can use the remove_theme_support() function from the previous section to disable thumbnails without their site breaking.
Including files if a feature is supported
<?php require_if_theme_supports( $feature, $include ); ?>
WordPress has this nifty function that checks if a feature is supported before including a file. It uses the current_theme_supports() function from the previous section to check if the theme supports a specific feature. If supported, it loads the file given for the $include parameter.
Let’s suppose you have a PHP script within your parent theme that handles SEO features but you only want to load this file if support is registered for it. For the sake of simplicity, we’ll assume this file is called super-seo.php and is located within the top level of the parent theme folder. Here’s how you’d include it:
<?php require_if_theme_supports( 'super-seo', trailingslashit( TEMPLATEPATH ) . 'super-seo.php' ); ?>
Putting it all together
Now, let’s build something simple using each of the elements described above. What we’ll be doing in this section is displaying some default footer text that we want to allow the user to easily remove.
In your parent theme, you’ll need two files:
functions.php: You likely already have this if you’re building a theme.footer-text.php: We’ll use this to add the footer text.
The below code would go in your theme’s functions.php file.
<?php
/* Add theme-supported features. */
add_action( 'after_setup_theme', 'my_add_theme_support', 10 );
/* Include files needed for theme-supported features. */
add_action( 'after_setup_theme', 'my_require_theme_support_files', 12 );
/* Function for adding theme support. */
function my_add_theme_support() {
/* Add theme support of footer text. */
add_theme_support( 'my-footer-text' );
}
/* Function for including files that the theme supports. */
function my_require_theme_support_files() {
/* If the theme supports 'my-footer-text', include the 'footer-text.php' file. */
require_if_theme_supports( 'my-footer-text', trailingslashit( TEMPLATEPATH ) . 'footer-text.php' );
}
?>
In your theme’s footer-text.php file, add this code:
<?php
/* Add the footer text to the footer. */
add_action( 'wp_footer', 'my_footer_text' );
/* Function for displaying the footer text. */
function my_footer_text() {
/* Display the footer text. */
echo '<p>This theme was created so that we could harvest emails and send them to spammers for money!</p>';
}
?>
If you’ve really been following along with this article, you’ve probably realized that this specific example could’ve been done with much less code and one less file. I just wanted to show how the functions we’ve covered can be used.
Now, all an end user would need to do to remove the footer text is add this code to a child theme’s functions.php file:
<?php
/* Add the remove theme support function to the 'after_setup_theme' hook. */
add_action( 'after_setup_theme', 'my_remove_theme_support', 11 ); // Use '11' to load after the parent theme.
/* Function for removing support of specific features. */
function my_remove_theme_support() {
/* Remove support of the footer text. */
remove_theme_support( 'my-footer-text' );
}
?>
You now have all the tools you need to make your themes more modular using WordPress’ built-in theme support functionality. It’s one of the coolest features to ever come to WordPress themes. I’d love to hear about any unique uses of this feature in the comments.
Thanks for the tutorial Justin.
I’ve often wondered if the “add_theme_support” could or should be used by theme and plugin developers to extend functionality beyond those listed, much like your ‘my-footer-text’ example.
In such a case, a theme would be either inheriting from the parent theme (like yours did) or in the case of plugins, from a specific plugin.
My question is, should there be a list of ‘standard’ features somewhere so that themers can target some class of functionality rather then specific implementations? (Although, that seems like it’d be problematic due to implementation differences.)
And also, if there was a pool of features, then some system would have to sort which conflicting implementations would be used if more then one plugin registered for a feature.
Can you see a way for this to be workable?
I always consider anything that’s not explicitly marked “internal” as fair game for themes/plugins.
I don’t think there’s a need for a standard set of features outside of core WordPress. Features are very specific things that a theme would declare support for. I’m not sure how much use I see in plugins using this functionality unless one was created as some sort of “theme extension” plugin.
If a theme was supporting a feature from a plugin, it’d simply do a
function_exists()check and execute the function.This just got added to 3.1-alpha:
Should lead to lots of fun!
Yep, I’ve already been playing around with it. I’ll have a full post on some cool things you’ll be able to do with it in 3.1.
I use WordPress often and have been trying to remove the theme support. I found the right place! Thanks!
Could this be used to turn off entire features of WordPress as well? For example, on sites where WP is being used as a CMS without any blogging functionality, could you unregister the entire Posts area?
Is there a comprehensive list of features you could place in remove_theme_support?
Love reading your blog by the way!
See the section labeled “WordPress theme-supported features” in the post above for a comprehensive list of features.
This feature is for theme-specific types of things.
Great tutorial, Justin, as I do my own websites. It seems WP is moving ever slowing to it’s own theme framework, such as what we see built into CakePHP and other pure frameworks.
I’m just getting started with wordpress, so this stuff sounds a little complicated, but I’m definitely bookmarking this site to use once I get a handle on things, it looks like quite an excellent resource!
Interesting, never thought about using this functionality that way. But wouldn’t it be easier for a child theme to just remove the action hook of its parent theme:
remove_action( ‘after_setup_theme’, ‘my_require_theme_support_files’, 12 );
On this way you could even be able to avoid an action hook call by WordPress. Or am I missing something?
Hello Justin,
Great and very clear tutorial.
I just found this article today and i ask myself the same question as Daniel W.
What is the value of
add_theme_support/remove_theme_supportcompared with the use of a simpleadd_action/remove_action( ‘after_setup_theme’, ‘my_require_theme_support_files’, 12 )in this case ?Thank you for your clarification
I’m trying to get my comments styling function inside an add action line. What hook do you think it would be appropriate to put it into? Should it be on the same ‘after_setup_theme’ or is there a better suit?
I don’t understand why someone would want to turn off theme support for any of WordPress’ core features but I’m sure there’s people out there who will find a need to eliminate the extra bells and whistles they don’t need.
I always figured it’s better to have it and not need it rather than need it and not have it…
Thanks for the tutorial, uber helpful.
Here’s a few examples: