After having spent quite some time figuring out how to use a custom theme-options.php (the file that sets the WooThemes options panel in the admin dashboard) in a child theme, without modifying the parent theme – I thought I’d post it here to save someone else the hassle!
Until recently I’ve been using a child theme for absolutely all changes I could – with one exception – the theme-options.php file. Every time I wanted to update the theme, I would have to add:require_once ( STYLESHEETPATH . '/includes/theme-options-custom.php' );
…after the following lines in the default theme-options.php file:
// THIS IS THE DIFFERENT FIELDS$options = array();This would make sure that my own include file loaded right before all of the default theme option entries, allowing me to add a few of my own in.
However this meant that the existing theme-options were still loaded after the custom ones, and would clutter up the theme options page with many no longer used entries. Also, the parent Aperture theme was not fully independent of the child theme, which made updating the parent theme more of a hassle, as files needed to be manually edited.
After reading the suggestions given here: http://forum.woothemes.com/topic.php?id=21563 , I tried doing something like:
remove_action( 'init', 'woo_options' );add_action( 'init', 'my_custom_woo_options' );However, this would always come up with a “Cannot redeclare category_boxes…..” error – implying that both the old and new options functions were being executed and not just the new one.
I managed to work out that this was due to Wordpress loading the child theme functions.php before the parent’s and not after. Therefore when the remove_action is performed, there is no woo_options function hooked into init to remove – since it has not yet been added yet.
This means that the remove_action needs to be deferred until after the parent theme’s function.php has been called as well – which is something that can be achieved using add_action. I first tried adding the remove_action to init, but that appears to be too late. So instead, an action hook after the theme functions.php are loaded, but before init action is needed.
If using WP 2.9.x or below you have to use the action hook ’set_current_user’, else if you are using WP3.0+, you can use the slightly more appropriate action hook of ‘after_setup_theme’. For more info on action hooks and their orders, see:
- http://codex.wordpress.org/Plugin_API/Action_Reference
- http://adambrown.info/p/wp_hooks
Anyway, enough of the explanations, here is the solution…
To have your own theme-options.php file in the child theme override the parent theme, do the following:
1) Copy ‘/parent-theme/includes/theme-options.php’ to ‘/child-theme/includes/theme-options.php’
2) Change the start of the child theme-options.php to:
<?phpfunction custom_woo_options(){…instead of:
<?phpfunction woo_options(){3a) For WP 3.0+, change the end of the file to:
add_action( 'after_setup_theme', create_function( '$a', "remove_action( 'init', 'woo_options' );" ) );add_action( 'init', 'custom_woo_options' );?>…instead of:
add_action('init','woo_options')?>3b) For WP 2.9.x or below, use this instead:
add_action( 'set_current_user', create_function( '$a', "remove_action( 'init', 'woo_options' );" ) );add_action( 'init', 'custom_woo_options' );?>4) Add this line to your child theme’s functions.php:
// Override WooThemes theme-options.php with own custom filerequire_once ( STYLESHEETPATH . '/includes/theme-options.php' );5) Make some alterations to the new child theme-options.php file and see them appear in the Admin Dashboard without having to touch the parent theme!
No comments:
Post a Comment