Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WordPress replace header.php from a plugin

Tags:

wordpress

I have searched and cant find any answer.

How can I replace the themes header.php template from a custom plugin?

Everywhere I look it seems like it cant be done, and you can only change template parts from a theme/child theme.

But how does plugins like Elementor page builder do it then in their theme builder?

Thanks, Daniel

like image 373
Daniel Persson Avatar asked Jun 06 '26 11:06

Daniel Persson


2 Answers

I also needed to include a custom header.php from my plugin. Because you can register templates like page.php, post.php or archive.php from a plugin via the ${type}_template hook, I thought it shouldn't be that difficult to do the same for the header.php, but you can't load a custom header.php from directories other than parent or child theme's one.

When traversing down the get_header function you'll see the locate_template function being invoked to load the header template. But there is no way to hook into that function and to replace the path for the loaded header template:

    function locate_template( $template_names, $load = false, $require_once = true, $args = array() ) {
        $located = '';
        foreach ( (array) $template_names as $template_name ) {
            if ( ! $template_name ) {
                continue;
            } 
            if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {
                $located = STYLESHEETPATH . '/' . $template_name;
                break; 
            } elseif ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {
                $located = TEMPLATEPATH . '/' . $template_name;
                break;
            } elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) {
                $located = ABSPATH . WPINC . '/theme-compat/' . $template_name;
                break;
            }
        }

        if ( $load && '' !== $located ) {
            load_template( $located, $require_once, $args );
        }

        return $located;
    }

One solution to bypass this limitation would be to get rid of the get_header function within your plugin's templates and to include the plugin's header.php via require or require_once statement from within the plugin's templates. But than you will have to implement your own get_header hook and locate_template functionality to enable replacement from the parent or child theme. See this answer for more information on limitations when omitting the get_header function: https://wordpress.stackexchange.com/a/5195/80177

like image 184
FullStack Alex Avatar answered Jun 08 '26 02:06

FullStack Alex


I used this solution

add_action('get_header', 'wpbet_replace_theme_header');

function wpbet_replace_theme_header(){

    require plugin_dir_path( __FILE__ ) . 'templates/headers/header-padrao.php';

    $templates   = [];
    $templates[] = 'header.php';
    remove_all_actions( 'wp_head' );
    ob_start();
    locate_template( $templates, true );
    ob_get_clean();

}
like image 37
Diogenes Oliveira Junior Avatar answered Jun 08 '26 01:06

Diogenes Oliveira Junior



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!