Page Templates from plugin not working after upgrading WP to 4.7 or upper version

I am working on a plugin which we need for education website. I have added 3-4 Page templates within my plugin so that we can call when plugin is activated.

Till WordPress 4.7, it was working perfectly; but as I upgraded WordPress to the latest (from 4.6.3), page templates don’t even show in page attribute section.

Here is the code which was working fine with older versions (before 4.7):

add_action( 'wp_loaded', 'add_my_templates' );
function add_my_templates() {
    if( is_admin() ){
        global $wp_object_cache;
        $current_theme = wp_get_theme();
        $templates = $current_theme->get_page_templates();
        $hash = md5( $current_theme->theme_root . '/'. $current_theme->stylesheet );
        $templates = $wp_object_cache->get( 'page_templates-'. $hash, 'themes' );
        $templates['templates/exams.php'] = __('Exams');
        $templates['templates/colleges.php'] = __('Colleges');
        $templates['templates/study_home.php'] = __('Study Home');
        $templates['templates/study_job_home.php'] = __('Study Job Home');
        wp_cache_replace( 'page_templates-'. $hash, $templates, 'themes' );
    }
    else {
        add_filter( 'page_template', 'get_my_template', 1 );
    }
}

function get_my_template( $template ) {
    $post = get_post();
    $page_template = get_post_meta( $post->ID, '_wp_page_template', true );
    if( $page_template == 'templates/study_home.php' ) {
        $template = plugin_dir_path(__FILE__) . "templates/study_home.php";
    }
    if( $page_template == 'templates/study_job_home.php' ) {
        $template = plugin_dir_path(__FILE__) . "templates/study_job_home.php";
    }
    if( $page_template == 'templates/exams.php' ) {
        $template = plugin_dir_path(__FILE__) . "templates/exams.php";
    }
    if( $page_template == 'templates/colleges.php' ) {
        $template = plugin_dir_path(__FILE__) . "templates/colleges.php";
    }
    return $template;
}

I am searching for the solution from last 2 days, but no luck!

Solutions Collecting From Web of "Page Templates from plugin not working after upgrading WP to 4.7 or upper version"

The Problem:

As Mark suggested already, your template loading by manipulating cache is far from standard practice. With these sort of cache alteration, even if you modify your CODE to work with WordPress 4.7+, there is no guarantee that you’ll not find similar problems in future updates. So better use any of the solutions mentioned below:

Theme Solution:

Instead of assigning templates form a plugin, you can have actual page templates in the active theme. Your active theme is the recommended place to have these page templates.

Plugin Solution

However, if you have to assign these templates with your plugin for some reason, then use the theme_page_templates hook to do so. It’ll work for WordPress 4.4+.

Following is the rewrite of your CODE using theme_page_templates filter hook:

function get_my_template( $template ) {
    $post = get_post();
    $page_template = get_post_meta( $post->ID, '_wp_page_template', true );
    if( $page_template == 'templates/study_home.php' ){
        return plugin_dir_path(__FILE__) . "templates/study_home.php";
    }
    if( $page_template == 'templates/study_job_home.php' ){
        return plugin_dir_path(__FILE__) . "templates/study_job_home.php";
    }
    if( $page_template == 'templates/exams.php' ){
        return plugin_dir_path(__FILE__) . "templates/exams.php";
    }
    if( $page_template == 'templates/colleges.php' ){
        return plugin_dir_path(__FILE__) . "templates/colleges.php";
    }
    return $template;
}

function filter_admin_page_templates( $templates ) {
    $templates['templates/exams.php'] = __('Exams');
    $templates['templates/colleges.php'] = __('Colleges');
    $templates['templates/study_home.php'] = __('Study Home');
    $templates['templates/study_job_home.php'] = __('Study Job Home');
    return $templates;
}

function add_my_templates() {
    if( is_admin() ) {
        add_filter( 'theme_page_templates', 'filter_admin_page_templates' );
    }
    else {
        add_filter( 'page_template', 'get_my_template', 1 );
    }
}

add_action( 'wp_loaded', 'add_my_templates' );

Use the above CODE instead of the CODE you’ve provided. It’ll work for any WordPress version 4.4 and later. I’ve tested it for WordPress 4.7.2 & it works fine.

Your caching insertion code looks very weird and depending on some specific way core calculates hashes for cache and uses them. You need to rewrite that part of the code (which I assume add virtual page templates) to find a more robust insertion method, or just abandon it totally (why not just have actual page templates?)

In general page template are a theme’s thing and plugins should not realy have one and instead provide shortcodes or other ways to let the user have pages with their data.