0

I have a client who wants to display home plans (a custom post type) on their website in 2 differently branded sections, depending on which listing page the post is accessed from. I found this solution from @gmazzap from a few years ago, and it looks promising, but I can't make it work: Multiple templates for custom post type

Specifically, it fails to modify the URL on the alternate listing page: it simply uses the slug specified in the CPT registration:

'rewrite' => array( 'slug' => 'plan', 'with_front' => false ),

Which means when I click a plan link on 'page_kioskoverview,php' template it displays the post on the standard 'single-plans.php' template rather than the alternate 'single-kioskplans.php' template.

Here's what my code looks like:

add_action('template_redirect', 'change_plans_plink');
function change_plans_plink() {
  if (is_page_template('page_kioskoverview.php')) { 
    add_filter( 'post_link', 'plans_query_string', 10, 2 );
  }
}
function plans_query_string( $url, $post ) {
  if ( $post->post_type === 'plans' ) { 
    $url = add_query_arg( array('style'=>'alt'), $url );
  }
  return $url;
}

//designate alternative single template for above alt link
add_action('template_include', 'kiosk_plan_single');
function kiosk_plan_single($template) {
  if( is_singular('plans') ) {
    $alt = filter_input(INPUT_GET, 'style', FILTER_SANITIZE_STRING);
    if ( $alt === 'alt' ) $template = 'single-kioskplans.php';
  }
  return $template;
}

After a few days looking at it (and trying some variations without success), I cannot spot the problem, but I must be missing something.

1

To display different templates for the same post type I would make 2 different links, check on which link I'm currently on and decide which template to load.

Working example:

/**
 * Register event post type
 *
 * Registering event post type will add such a permalink structure event/([^/]+)/?$
 */
function wpse_288345_register_event_post_type() {

    $labels = array(
        'name' => __( 'Events' ),
        'singular_name' => __( 'Event' ),
        'add_new' => __( 'Add new' ),
        'add_new_item' => __( 'Add new' ),
        'edit_item' => __( 'Edit' ),
        'new_item' => __( 'New' ),
        'view_item' => __( 'View' ),
        'search_items' => __( 'Search' ),
        'not_found' => __( 'Not found' ),
        'not_found_in_trash' => __( 'Not found Events in trash' ),
        'parent_item_colon' => __( 'Parent' ),
        'menu_name' => __( 'Events' ),

    );

    $args = array(
        'labels' => $labels,
        'hierarchical' => false,
        'supports' => array( 'title', 'page-attributes' ),
        'taxonomies' => array(),
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        'show_in_nav_menus' => false,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => array('slug' => 'event'),
        'capability_type' => 'post',
    );

    register_post_type( 'event', $args );
}

add_action( 'init', 'wpse_288345_register_event_post_type' );

/**
 * Add custom rewrite rule for event post type.
 *
 * Remember to flush rewrite rules to apply changes.
 */
function wpse_288345_add_event_rewrite_rules() {

    /**
     * Custom rewrite rules for one post type.
     * 
     * We wil know on which url we are by $_GET parameters 'performers' and 'summary'. Which we will add to
     * public query vars to obtain them in convinient way.
     */
    add_rewrite_rule('event/performers/([^/]+)/?$', 'index.php?post_type=event&name=$matches[1]&performers=1', 'top');
    add_rewrite_rule('event/summary/([^/]+)/?$', 'index.php?post_type=event&name=$matches[1]&summary=1', 'top');
}

add_action('init', 'wpse_288345_add_event_rewrite_rules');

/**
 * Add 'performers' and 'summary' custom event query vars.
 */
function wpse_288345_register_event_query_vars( $vars ) {

    $vars[] = 'performers';
    $vars[] = 'summary';

    return $vars;
}

add_filter( 'query_vars', 'wpse_288345_register_event_query_vars' );

/**
 * Decide which template to load
 */
function wpse_288345_load_performers_or_summary_template( $template ) {

    // Get public query vars
    $performers = (int) get_query_var( 'performers', 0 );
    $summary    = (int) get_query_var( 'summary', 0 );

    // If performer = 1 then we are on event/performers link
    if( $performers === 1 ) {
        $template = locate_template( array( 'single-event-performers.php' ) );
    }

    // If summary = 1 then we are on event/summary link
    if( $summary === 1 ) {
        $template = locate_template( array( 'single-event-summary.php' ) );
    }

    if($template == '') {
        throw new \Exception('No template found');
    }

    return $template;
}

add_filter( 'template_include', 'wpse_288345_load_performers_or_summary_template' );
  • 1
    I found an alternative simple solution, but I'm going to mark this as the answer because it responds more closely to my question. I will also test this out report back if it works. Looks veery promising. – Ray Gulick Dec 12 '17 at 15:11
0

Here's the alternative approach that I made work, using a GET parameter and conditional statements.

  1. On the alternate listing page, I added '?template=kiosk' to the permalinks.

  2. On the singles template (single-plans.php) I added the following to the top of the template (and of course 'endif' at bottom of template):

    $kiosk = $_GET['template'];
    if(isset($kiosk)) :
  3. Then, throughout the template, I created conditional statements based on whether or not there was a parameter, to display content appropriately:

    if(isset($kiosk)) { 
        show kiosk version
        } else {
        show standard version
        }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.