Advanced Child Theme Usage

Click here to go back to our child theme setup index.

 

So far in our child theme series we’ve looked at how to create a basic child theme and also how to take it a bit further by overriding template files. This time we’re going to look at some more advanced usage by replacing functions in a parent theme with a new one in our child theme.

For an example we’re going to replace the featured product widget that’s in our Elite theme with one that’s in our child theme. We’ve already copied the actual file to our child theme and made the changes there. But unlike file like single.php or page.php, WordPress seems to ignore the file in our child theme. That’s because the file in the parent theme is loaded via a function. So to change the function, we need to override it with a new one in the child theme. Here’s how to do that.

  1. Create a functions.php file in your child theme. Start the file off with <?php
  2. Next copy the function from the parent theme that contains the loading of the widgets and paste it into the child theme’s functions.php file. In our Elite theme it looks like this:
    // Load Other Files
    if ( ! function_exists( 'elite_files' ) ):function elite_files() {
    
    // include required files
    include(get_template_directory()."/includes/fonts.php");
    include(get_template_directory()."/includes/titles.php");
    include(get_template_directory()."/includes/images.php");
    include(get_template_directory()."/includes/queries.php");
    include(get_template_directory()."/includes/scripts.php");
    include(get_template_directory()."/includes/body-tag.php");
    include(get_template_directory()."/includes/custom-js.php");
    include(get_template_directory()."/includes/shortcodes.php");
    include(get_template_directory()."/includes/custom-css.php");
    include(get_template_directory()."/includes/author-fields.php");
    include(get_template_directory()."/includes/content-limit.php");
    include(get_template_directory()."/includes/tha-theme-hooks.php");
    include(get_template_directory()."/includes/theme-customizer.php");
    include(get_template_directory()."/includes/comment-functions.php");
    include(get_template_directory()."/includes/custom-meta-boxes/elite.php");
    
    // Custom Post Types
    include(get_template_directory()."/includes/post-types/staff.php");
    include(get_template_directory()."/includes/post-types/slides.php");
    include(get_template_directory()."/includes/post-types/testimony.php");
    include(get_template_directory()."/includes/post-types/admin-style.php");
    
    // include widgets
    include(get_template_directory()."/includes/widgets.php");
    include(get_template_directory()."/includes/widget-page.php");
    include(get_template_directory()."/includes/widget-posts.php");
    include(get_template_directory()."/includes/widget-video.php");
    include(get_template_directory()."/includes/widget-social.php");
    include(get_template_directory()."/includes/widget-product.php");
    include(get_template_directory()."/includes/widget-testimony.php");
    include(get_template_directory()."/includes/widget-attention.php");
    include(get_template_directory()."/includes/widget-featured-page.php");
    include(get_template_directory()."/includes/widget-facebook-like-box.php");
    
    }
    
    endif; // elite_files
    
    add_action( 'after_setup_theme', 'elite_files' );
    

    It’s very important that the function begins with a statement like
    if ( ! function_exists( 'elite_files' ) ):

    If it does not, then you won’t be able to override it with the child theme using this method.

  3. Find the line that loads the widget you’d like to use. For the Featured Product widget, it’s include(get_template_directory()."/includes/widget-product.php");
  4. WordPress has two functions that do similar things. The get_template_directory() function will load a file from the parent theme. The get_stylesheet_directory() function will load from the child theme if there is one. So, we’ll want to changeinclude(get_template_directory()."/includes/widget-product.php");

    to

    include(get_stylesheet_directory()."/includes/widget-product.php");

  5. Save your changes.

That should cause WordPress to load our new widget from the child theme instead of the parent. Now we can make any changes to the widget without worrying about losing them in an update.

You can take this principal and make other changes to the theme’s functionality this way. Sometimes when I need to modify the extra metaboxes in a theme, I will use this method to load a new copy of them from a child theme by overriding the function that loads them in the parent.

So that’s a quick run-through of how to make changes to a theme’s functionality by using a child theme. With these tools you should be able to do just about anything you want to with a child theme now.

13 Comments

Shannon June 9, 2016

This is just what I was looking for! Thank you for the missing piece of the puzzle 🙂

Reply

louis October 29, 2015

Hello Bill,

Apologies for being so late here, what i’m trying to do is adjust some lines in my parent themes widgets.php via the use of a child theme.

I went to functions.php in my parent and copied the line that says
include get_template_directory() . ‘/inc/widgets.php’;

(this line is not in an if statement)

and I paste it in to my functions.php in child theme and changed it to

include get_stylesheet_directory() . ‘/inc/widgets.php’;

to call the edited widgets.php that is in my child theme.

Didn’t work, do you know where I’m going wrong?

Reply

    Bill Robbins October 29, 2015

    Hi Louis,

    Great question. In order to override a function, like the code inside widgets.php with a child theme, the code in the parent theme has to be inside an if statement or can be modified via a filter.

    Since that line isn’t in a if statement in your parent theme, here’s what I would do. I would suggest commenting out that line in the parent theme by adding this:


    //

    at the beginning of the line. That way when you go to load it in your child theme that code won’t have been loaded in the parent too. You might ask the developer to wrap that function in an if statement so you can override it more easily in the future.

    Hope that helps,
    Bill

    Reply

Neko June 7, 2015

Hello Bill, I hope it’s not too late to ask a question concerning this.

I’ve been running through the code for a theme I’m working with, but I can’t seem to find anything suitable to replace ‘elite_files’. What would that function look like normally, and would it be found in the functions.php file? It might be that the theme just doesn’t support editing widgets, but I thought I’d ask just in case I was missing something.

Great tutorial by the way. I can’t believe no one really thought to explain this so thoroughly until now. Thanks for your hard work!

Reply

    Bill Robbins June 8, 2015

    Hey Neko, not too late to ask at all. It sounds like the widget is being loaded from that function in the functions.php file. If the function is wrapped with something like this:

    if ( ! function_exists( 'elite_files' ) ):

    then what you can do is copy the actual function from the parent theme and place it in the child theme. Keep it just like it is, except for the call that loads the widget you want to change. Say it looks like this:


    include( get_template_directory()."/includes/widget-social.php" );

    What you would do there is change the get_template_directory (which tells WordPress to look inside the parent theme) to get_stylesheet_directory (which tells WordPress to look in the child theme if it exists). Then you can copy the widget file to the child theme, keeping the same directory structure and edit away.

    Hope that helps out 🙂

    Reply

manisha April 11, 2015

Hi, First of all thanks for this nice tutorial.
I did everything in a same way you explained and after that I got the same issue cannot redeclare class. After that I fixed this via renaming the class. But after that I am seeing same content twice.

Like this is the class: new HRB_Edit_Profile_Social_Meta_Box_child

n new HRB_Edit_Profile_Social_Meta_Box being called from parent theme. This is how I am getting content twice. Could you please suggest me some solution in able to fix this duplicacy.

Hope you get my issue. Looking for solution asap.

Thank you

Reply

    Bill Robbins April 13, 2015

    Good Morning Manisha,

    It sounds like the original theme wasn’t set up to allow you to replace this function. You discovered that simply copying the function caused things to crash since it duplicates the name. But changing the name of the function in the child theme, only duplicates the output because WordPress doesn’t know that you’re trying to override an existing function.

    One option would be to look and see if there are any functions that load this one that are wrapped in a if_exists statement. You may have to replace a higher up function in order to cause this to work.

    If that’s not possible, then you’ll have to edit the parent theme directly. A WordPress theme has to be created in a certain way for this type of customization to be possible. The author of the theme may not have done that. If they haven’t there’s not much you can do. This part depends on them

    Just keep a separate copy of your customizations in case you need to add them again after an update. It’s not ideal, but it may be your only real option.

    Bill

    Reply

alan March 24, 2015

Hi Bill,
Very helpful, but I am having an error :
I have added code :
include(get_template_directory().”/inc/widgets/widgets.php”);

but error is :

Fatal error: Cannot redeclare spacious_widgets_init() (previously declared in /home/url/wp-content/themes/spacious/inc/widgets/widgets.php:17) in /home/url/wp-content/themes/spacious-child/inc/widgets/widgets.php on line 166

it seems both file widgets.php are called ?
Thanks

Reply

    Bill Robbins March 25, 2015

    Good question. It sounds like the function that sets up widgets is not wrapped in a conditional “if exists” statement. So that’s causing two functions to have the same name which isn’t allowed.

    You can change the name of the spacious_widgets_ir function that’s in your child theme. It’ll likely be in that file twice so change it in both spots.

    That should let that function work, though it won’t replace the one in the parent. The parent theme needs to have the “if_exists” conditional for replacement to be pissible.

    Reply

Francis January 6, 2015

The explanation really clear things up for me before diving in creating my own child-theme wp. Thanks for sharing.

Reply

Steve December 4, 2014

Very helpful! In the WP Codex they don’t really explain how to override enqueued files. They make it sound like any replacement file you put in the child theme will be selected automatically, but that only works for template files in the WP hierarchy.

Still, I feel like child themes is missing a level of granularity. If a function in my parent theme is updated, my child theme is still using the modified function from before the update.

Reply

    Bill Robbins December 4, 2014

    Glad that helped you out. Child themes do help out a good bit with updating, but it is a solution with compromises.

    Reply

Submit your comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Get all themes with lifetime updates for 95 USD.View All Promotions
+ +