Dynamically override page.php or single.php with custom templates using function

One way you can do that is by adding a filter to the hook {$type}_template.

Sample code:

function my_plugin_custom_template( $template, $type ) {
    switch ( $type ) {
        case 'page':
            $template="/path/to/custom-page-template";
            break;

        case 'single':
            $template="/path/to/custom-single-template";
            break;
    }
    return $template;
}
add_filter( 'page_template', 'my_plugin_custom_template', 10, 2 );   // Filter for page.php
add_filter( 'single_template', 'my_plugin_custom_template', 10, 2 ); // Filter for single.php

Or you can also add a filter to the hook template_include.

Sample code:

function my_plugin_custom_template2( $template ) {
    if ( is_page() ) {
        $template="/path/to/custom-page-template";
    }
    elseif ( is_single() ) {
        $template="/path/to/custom-single-template";
    }
    return $template;
}
add_filter( 'template_include', 'my_plugin_custom_template2' );

It’s up to you to decide which hook to filter; however, the template_include filter is called after the {$type}_template hook. And if you look at the my_plugin_custom_template() code, you basically don’t need to check whether the current page (i.e. queried object) is a Page, Post, etc.

Hope that helps.

Leave a Comment