get_stylesheet_directory() vs get_template_directory() for child theme

locate_template will attempt to find the specified file in the child theme, and fall back to the parent theme if it does not exist:

locate_template('inc/custom.php', true);

Setting the second parameter to true causes it to require the file instead of just determining the path.

As the name suggests, locate_template is meant for loading template files. It has some additional overhead that you most likely don’t need for loading libraries. A stripped down version would be:

function load_theme_file($path) {
    if ( file_exists( STYLESHEETPATH . "https://wordpress.stackexchange.com/" . $path )) {
        include( STYLESHEETPATH . "https://wordpress.stackexchange.com/" . $path );
    } else {
        require( TEMPLATEPATH . "https://wordpress.stackexchange.com/" . $path );
    }
}

Usage:

load_theme_file('inc/custom.php');

Edit: I just wanted to provide a quick note about potential issues with this overall approach.

Letting a child theme override files works well for templates, but for libraries there is more room for error. If a child theme needs to modify a single function, you would have to copy that entire file, overriding every function in that file in the process.

If the parent theme is updated and changes have been made to any of the functions in the overwritten file it can cause problems. You can mitigate this issue by breaking up your libraries into smaller chunks, but that can make your code base harder to maintain.

A better solution, in my opinion, is to use an object oriented approach. Allow a child theme to extend classes you define and then use the child theme’s class. In the implementing classes the child theme would only have to define methods it needs to overwrite. In the parent theme you could specify which methods should not be overwritten by making them final.

You can also mitigate the need for child themes to replace entire files by using filters and actions generously.

Leave a Comment