WordPress Child Themes and remove_theme_support

One of the interesting new features in WP 3.0 is child themes. This is a way to customize a given — “parent” — theme without copying or directly modifying the original theme files. This way, when the original theme is updated, you can update its files without losing your customizations.

To create a child theme, you create a new style.css file in a directory parallel to the parent theme’s directory. This style.css will override and replace the parent theme’s style.css unless you import it explicitly. Typically, you import the parent’s style.css at the beginning of your style.css and then selectively override anything you don’t like.

Optionally, you can also define a new functions.php which will be loaded before the parent’s functions.php.

Read that last sentence again. Intuitively, if you want to override the parent theme’s functions.php, shouldn’t the parent’s version be loaded before the child’s?

I’m not the first person to point this out. You can see the WP bug filed about it, and the developers’ explanation for why this is a WON’T FIX. I find this behavior unintuitive, and I’m sure others will too. You have to learn to work around it.

The right way to do this is to use the after_setup_theme hook to allow the child theme to delay execution of any code until the parent theme is done loading. If you look in wp-settings.php, you’ll see the following:

// Load the functions for the active theme, for both parent and child theme if applicable.
if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) )
    include( STYLESHEETPATH . '/functions.php' );
if ( file_exists( TEMPLATEPATH . '/functions.php' ) )
    include( TEMPLATEPATH . '/functions.php' );
 
do_action( 'after_setup_theme' );

Looks good, right? But it doesn’t always work. If you try to use the after_setup_theme hook to run remove_theme_support in order to remove some feature that was added by the parent theme, it doesn’t seem to accomplish what’s intended. (I tried this with automatic-feed-links and couldn’t get the child theme to remove the feature from the parent theme.)

So you are left with the rather ugly choice of essentially copying the parent theme’s function — hopefully defined within a function_exists block — into your functions.php, and then modify the code directly in there. This is, however, the “official” workaround documented in the TwentyTen default theme.

To override twentyten_setup() in a child theme, add your own twentyten_setup to your child theme’s functions.php file.

I should probably file a bug about this.