Multiple templates for custom post type

The easiest way.
Create a page template, calling it e.g. “Alternative Product Page”. So create a php file and name it e.g. page-products-2.php.

In first two lines of this file put:

<?php
/*
Template Name: Alternative Product Page
*/

If you want that page design is exactly the same of the first product page (that I assume is called page-products.php), in the file just add

require 'page-products.php';

If you want to change some design, copy the first page file and modify it like you want.
If your theme is developed by third party, probably is better to do those tasks on a child theme.

Now in your backend assign to the second page the template you have just created.
Doing so you will able to recognize whe user is on that page without relying on its ID or title or something else. In addition you can have same behaviour in more than one page, if you want.

Once you recognize the page you can add a filter on single permalink when in this page:

add_action('template_redirect', 'change_product_plink');

function change_product_plink() {
  if ( is_page_template('page-products-2.php') ) { // remember to use real file name
    add_filter( 'post_link', 'product_query_string', 10, 2 );
  }
}

function product_query_string( $url, $post ) {
  if ( $post->post_type === 'product' ) {
    $url = add_query_arg( array('style'=>'alt'), $url );
  }
  return $url;
}

Using this code, when in the alternate page template, something like '?style=all' will be appended to all the product permalinks.

Finally, add a filter on template_include to use the alternative template when in singular product view and that query var is setted.

add_action('template_include', 'maybe_alt_product_single');

function maybe_alt_product_single($template) {
  if( is_singular('product') ) {
    $alt = filter_input(INPUT_GET, 'style', FILTER_SANITIZE_STRING);
    if ( $alt === 'alt' ) $template = locate_template('single-products2.php');
  }
  return $template;
}

Leave a Comment