Mostrar el mismo tipo de publicación personalizada en 2 plantillas single diferentes
Tengo un cliente que quiere mostrar planos de casas (un tipo de publicación personalizada) en su sitio web en 2 secciones con diferente marca, dependiendo de desde qué página de listado se acceda al post. Encontré esta solución de @gmazzap de hace algunos años, que parece prometedora, pero no logro hacerla funcionar: Plantillas múltiples para tipos de publicación personalizada
Específicamente, falla al modificar la URL en la página de listado alternativo: simplemente usa el slug especificado en el registro del CPT:
'rewrite' => array( 'slug' => 'plan', 'with_front' => false ),
Lo que significa que cuando hago clic en un enlace de plano en la plantilla 'page_kioskoverview.php', muestra el post en la plantilla estándar 'single-plans.php' en lugar de la alternativa 'single-kioskplans.php'.
Así es como luce mi código:
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;
}
//designar plantilla single alternativa para el enlace alt
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;
}
Después de varios días revisándolo (y probando algunas variaciones sin éxito), no logro identificar el problema, pero debe haber algo que me estoy perdiendo.

Para mostrar diferentes plantillas para el mismo tipo de publicación, crearía 2 enlaces diferentes, verificaría en qué enlace estoy actualmente y decidiría qué plantilla cargar.
Ejemplo funcional:
/**
* Registrar tipo de publicación de evento
*
* Registrar el tipo de publicación de evento agregará una estructura de enlace permanente como event/([^/]+)/?$
*/
function wpse_288345_register_event_post_type() {
$labels = array(
'name' => __( 'Eventos' ),
'singular_name' => __( 'Evento' ),
'add_new' => __( 'Agregar nuevo' ),
'add_new_item' => __( 'Agregar nuevo' ),
'edit_item' => __( 'Editar' ),
'new_item' => __( 'Nuevo' ),
'view_item' => __( 'Ver' ),
'search_items' => __( 'Buscar' ),
'not_found' => __( 'No encontrado' ),
'not_found_in_trash' => __( 'No se encontraron Eventos en la papelera' ),
'parent_item_colon' => __( 'Padre' ),
'menu_name' => __( 'Eventos' ),
);
$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' );
/**
* Agregar regla de reescritura personalizada para el tipo de publicación de evento.
*
* Recuerda vaciar las reglas de reescritura para aplicar los cambios.
*/
function wpse_288345_add_event_rewrite_rules() {
/**
* Reglas de reescritura personalizadas para un tipo de publicación.
*
* Sabremos en qué URL estamos mediante los parámetros $_GET 'performers' y 'summary'. Los cuales agregaremos a
* las variables de consulta públicas para obtenerlos de manera conveniente.
*/
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');
/**
* Agregar variables de consulta personalizadas 'performers' y 'summary' para eventos.
*/
function wpse_288345_register_event_query_vars( $vars ) {
$vars[] = 'performers';
$vars[] = 'summary';
return $vars;
}
add_filter( 'query_vars', 'wpse_288345_register_event_query_vars' );
/**
* Decidir qué plantilla cargar
*/
function wpse_288345_load_performers_or_summary_template( $template ) {
// Obtener variables de consulta públicas
$performers = (int) get_query_var( 'performers', 0 );
$summary = (int) get_query_var( 'summary', 0 );
// Si performer = 1 entonces estamos en el enlace event/performers
if( $performers === 1 ) {
$template = locate_template( array( 'single-event-performers.php' ) );
}
// Si summary = 1 entonces estamos en el enlace event/summary
if( $summary === 1 ) {
$template = locate_template( array( 'single-event-summary.php' ) );
}
if($template == '') {
throw new \Exception('No se encontró la plantilla');
}
return $template;
}
add_filter( 'template_include', 'wpse_288345_load_performers_or_summary_template' );

Aquí está el enfoque alternativo que logré hacer funcionar, utilizando un parámetro GET y declaraciones condicionales.
En la página de listado alternativo, agregué '?template=kiosk' a los enlaces permanentes.
En la plantilla individual (single-plans.php) agregué lo siguiente al principio de la plantilla (y por supuesto 'endif' al final de la plantilla):
$kiosk = $_GET['template']; if(isset($kiosk)) :
Luego, a lo largo de la plantilla, creé declaraciones condicionales basadas en si había o no un parámetro, para mostrar el contenido apropiadamente:
if(isset($kiosk)) { mostrar versión kiosko } else { mostrar versión estándar }

Estaba intentando casi exactamente el mismo código también, y no funcionaba. Solo hay un cambio que hacer para que esto opere completamente. Solo agrega locate_template
a una línea.
Cambia
if ( $alt === 'alt' ) $template = 'single-kioskplans.php';
por
if ( $alt === 'alt' ) $template = locate_template('single-kioskplans.php');
El código completo se verá así:
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;
}
//designar plantilla single alternativa para el enlace alt anterior
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 = locate_template('single-kioskplans.php');
}
return $template;
}
