Programmatically set page template based on page ID

How would I set the page template based on the ID? I have Redux Framework installed in my site and one of the options is to set a registration page. On this page, I want to use a specific template, but on others it should use the default templates.

I have had it half-working with

add_filter( 'page_template', 'my_function' );
function my_function(){
  global $my_options;
  $page_id = get_queried_object_id();
  if ( $my_options['my-reg-page'] == $page_id ) {
    return get_template_directory() . '/reg-page.php'; 
  }
}

in that the page in question (the one with the ID stored in $my_options['my-reg-page']) has the page set, but the remaining pages use index.php as the template and not their appropriate pages (single.php, page.php, etc.). If I set the conditional outside of the filter, it won’t display the template I am looking for. I want to avoid saving meta data, as I would rather stick the code into my functions.php file to use in multiple themes, which would use different pages as the relevant page, where needed. I know the easiest way to do it is to set the theme directly on the page in the admin area, but that creates multiple options as it is. I’m hoping to reduce them as much as possible.

Any advice? Is it even possible?

1 Answer
1

I needed to do something very similar for one of the plugins that I was developing. I registered two separate cpt’s during plugin activation, and each of those cpt’s should use a custom single template that I had bundled with the plugin code base.

You should be able to do the same for page templates, using the page_template filter.

Here is my function using the single_template filter, which can be adjusted to use page_template instead. You’ll simply need to grab the global $post variable so you can check the post type or the post ID and then serve a template based on that data.

add_filter( 'page_template', 'custom_page_template' );
public function custom_page_template( $page_template ) {
        global $post;

        switch ( $post->ID) {

            default :
            case '2' : // page ID 2
                if( file_exists( get_stylesheet_directory() . '/single-event-template.php' ) ) {
                    $page_template = get_stylesheet_directory() . '/single-event-template.php'; 
                return $single_template;
            break;

            case '14' : // page ID 14
                $page_template= plugin_dir_path( dirname( __FILE__ ) ) . 'public/partials/single-event-location-template.php';
                return $page_template;
            break;

        } // end switch

}

I haven’t tested this using page templates, but from the codex page this seems like it should work.

Working off your example, you may want to try something similar to the following:

add_filter( 'page_template', 'my_function' );
function my_function( $page_template ){
  global $post;
  $page_id = $post->ID;
  if ( $my_options['my-reg-page'] == $page_id ) {
    $page_template = get_template_directory() . '/reg-page.php'; 
  } else {
   $page_template = get_template_directory() . '/some-other-page-template.php'; 
  } 
  return $page_template;
}

Leave a Comment