How to override parent theme functions in WordPress

If you’re a WordPress theme developer/customizer you’ll have probably encountered the need to modify parent theme properties in a child theme. Different entities work differently:

  • Templates: php templates are totally replaced by the child theme if the file has the same name,
  • Styling: css is appended (because you’re are actually including the parent’s css to the top of the child’s) so any object with the same id will be overwritten.
  • Functions: but functions from the functions.php don’t work in the same way. Functions in your child theme will be loaded before the functions in the parent theme. This means that if your parent and child themes both have functions called my_function() which do a similar job, the one in the parent theme will load last, meaning it will override the one in the child theme.

However, there are three ways to change the order in which functions are fired, and you can prevent functions from being fired altogether:

  • Pluggable functions
  • Function priority
  • Removing functions from the hook they’re attached to

Pluggable functions

When writing a parent theme, it’s good practice to make your functions pluggable so that you can easily override them in child themes. This simply means to wrap them in a conditional tag with PHP’s function_exists() to check if a function with that name has already been run. This way the parent theme function does not override one the child theme, thus giving power to the child theme developer to rewrite parent functions just by maintaining it’s name.

This is how the parent theme should look like:

if ( ! function_exists ( 'my_function' ) ) {
    function my_function() {
        // Contents of your function here.

This is what you’d write in the child theme:

function my_function() {
    // Contents for your function override here.

Function Priority

Sometimes pluggable functions are not available. Good practice wise, this is not acceptable for a good parent theme, but in reality there are frameworks out there so complicated and being maintained for so long, that functions exist outside functions.php and are usually not pluggable. This was my case so I had to seek further to be able to override them.

In WordPress, when adding your functions to an action or filter hook, you can assign a priority level to it. Functions will be added to the hook in ascending order. For instance:

function your_function() {
    // Contents for your function here.
add_action( 'init', 'parent_function', 20 );

This your_function() is hooked on init and has a priority of 20. So rewriting a child theme with priority 25 will override it’s behaviour:

function your_function() {
    // Contents for your function here.
add_action( 'init', 'parent_function', 25 );

But priorities are optional. On omission, WordPress will understand a priority of 10, so a priority 15 on a child theme function will be overriding it.

Removing Functions From Hooks

But sometimes, overloading a function is not enough to avoid it’s original behaviour after all. In this case you’ll need to actually de-hook the parent function and hook your child theme function instead by using remove_action() and remove_filter(). The one you use will depend on whether the function is attached to an action hook or filter hook in the parent theme.

To remove an function simply do:

remove_action( 'init', 'parent_function' );

However, this won’t work on its own, you need to attach this function to a hook which will fire after the hook which the parent theme function is attached to. This is because you can’t remove the action before it’s been fired.

function child_remove_parent_function() {
    remove_action( 'init', 'parent_function', [priority level] );
add_action( 'wp_loaded', 'child_remove_parent_function' );

NOTE: If the parent_function() was loaded using a priority level, you have to unloaded by stating the same level as well. That’s why [priority level] is in square brackets.

As you may imagine, wp-loaded is a hook that comes after init, so remove_action() can really remove the parent_function() that was loaded to init.

If what you want it was to delete a parent function, that’s all there is. If you would like to rewrite it, now you’re free to write whatever new function you’d like.

function child_function() {
    // your function
add_action( 'init', 'child_function' );

Author: Bea Cabrera

Freelance Filmmaker with a passion for big cities, snowboard, cinema and a weakness for the smell of freshly ground coffee. Engineer & Graphic Designer in a previous life, loving and living both: art and technology.  

Leave a Reply

Your email address will not be published.

You may use these <abbr title="HyperText Markup Language">html</abbr> tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


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