Cum să afișezi același tip de postare personalizată pe 2 șabloane single diferite
Am un client care dorește să afișeze planuri de casă (un tip de postare personalizată) pe site-ul său în 2 secțiuni cu brand diferit, în funcție de pagina de listare de pe care se accesează postarea. Am găsit această soluție de la @gmazzap de acum câțiva ani și pare promițătoare, dar nu reușesc să o fac să funcționeze: Șabloane multiple pentru tipuri de postare personalizate
Mai exact, nu reușește să modifice URL-ul pe pagina alternativă de listare: pur și simplu folosește slug-ul specificat în înregistrarea CPT:
'rewrite' => array( 'slug' => 'plan', 'with_front' => false ),
Ceea ce înseamnă că atunci când dau click pe un link de plan în șablonul 'page_kioskoverview.php', acesta afișează postarea pe șablonul standard 'single-plans.php' în loc de șablonul alternativ 'single-kioskplans.php'.
Iată cum arată codul meu:
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;
}
//desemnează șablonul single alternativ pentru link-ul alternativ de mai sus
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;
}
După câteva zile de analiză (și încercând câteva variații fără succes), nu reușesc să identific problema, dar cu siguranță îmi scapă ceva.

Pentru a afișa șabloane diferite pentru același tip de postare, aș crea 2 legături diferite, aș verifica pe ce legătură mă aflu în prezent și aș decide ce șablon să încarc.
Exemplu funcțional:
/**
* Înregistrează tipul de postare pentru evenimente
*
* Înregistrarea tipului de postare pentru evenimente va adăuga o structură de permalink event/([^/]+)/?$
*/
function wpse_288345_register_event_post_type() {
$labels = array(
'name' => __( 'Evenimente' ),
'singular_name' => __( 'Eveniment' ),
'add_new' => __( 'Adaugă nou' ),
'add_new_item' => __( 'Adaugă nou' ),
'edit_item' => __( 'Editează' ),
'new_item' => __( 'Nou' ),
'view_item' => __( 'Vezi' ),
'search_items' => __( 'Caută' ),
'not_found' => __( 'Nu a fost găsit' ),
'not_found_in_trash' => __( 'Nu s-au găsit Evenimente în coșul de gunoi' ),
'parent_item_colon' => __( 'Părinte' ),
'menu_name' => __( 'Evenimente' ),
);
$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' );
/**
* Adaugă reguli personalizate de rescriere pentru tipul de postare eveniment.
*
* Nu uita să resetezi regulile de rescriere pentru a aplica modificările.
*/
function wpse_288345_add_event_rewrite_rules() {
/**
* Reguli personalizate de rescriere pentru un tip de postare.
*
* Vom ști pe ce URL ne aflăm prin parametrii GET 'performers' și 'summary'.
* Îi vom adăuga la variabilele publice de interogare pentru a le obține într-un mod convenabil.
*/
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');
/**
* Adaugă variabilele personalizate 'performers' și 'summary' pentru interogarea evenimentelor.
*/
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 ce șablon să încarce
*/
function wpse_288345_load_performers_or_summary_template( $template ) {
// Obține variabilele publice de interogare
$performers = (int) get_query_var( 'performers', 0 );
$summary = (int) get_query_var( 'summary', 0 );
// Dacă performer = 1 atunci suntem pe link-ul event/performers
if( $performers === 1 ) {
$template = locate_template( array( 'single-event-performers.php' ) );
}
// Dacă summary = 1 atunci suntem pe link-ul event/summary
if( $summary === 1 ) {
$template = locate_template( array( 'single-event-summary.php' ) );
}
if($template == '') {
throw new \Exception('Nu s-a găsit niciun șablon');
}
return $template;
}
add_filter( 'template_include', 'wpse_288345_load_performers_or_summary_template' );

Iată abordarea alternativă pe care am făcut-o să funcționeze, folosind un parametru GET și instrucțiuni condiționale.
Pe pagina alternativă de listare, am adăugat '?template=kiosk' la permanent links.
Pe șablonul pentru pagini individuale (single-plans.php) am adăugat următoarele la începutul șablonului (și bineînțeles 'endif' la sfârșitul șablonului):
$kiosk = $_GET['template']; if(isset($kiosk)) :
Apoi, de-a lungul șablonului, am creat instrucțiuni condiționale bazate pe prezența sau absența parametrului, pentru a afișa conținutul corespunzător:
if(isset($kiosk)) { afișează versiunea kiosk } else { afișează versiunea standard }

Am încercat și eu codul aproape identic și nu funcționa. Există o singură modificare necesară pentru a face totul să funcționeze corect. Trebuie doar să adaugi locate_template
pe o linie.
Schimbă
if ( $alt === 'alt' ) $template = 'single-kioskplans.php';
în
if ( $alt === 'alt' ) $template = locate_template('single-kioskplans.php');
Codul complet va arăta astfel:
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;
}
//desemnează un șablon single alternativ pentru link-ul 'alt' de mai sus
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;
}
