Come visualizzare lo stesso custom post type su 2 template single diversi

11 dic 2017, 18:33:30
Visualizzazioni: 1.32K
Voti: 1

Ho un cliente che vuole visualizzare i piani casa (un custom post type) sul suo sito in due sezioni con branding diverso, a seconda della pagina di elenco da cui si accede al post. Ho trovato questa soluzione di @gmazzap di qualche anno fa, che sembra promettente, ma non riesco a farla funzionare: Multiple templates for custom post type

Nello specifico, non riesce a modificare l'URL sulla pagina di elenco alternativa: utilizza semplicemente lo slug specificato nella registrazione del CPT:

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

Ciò significa che quando clicco su un link del piano nel template 'page_kioskoverview.php', il post viene visualizzato sul template standard 'single-plans.php' anziché su quello alternativo 'single-kioskplans.php'.

Ecco come appare il mio codice:

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;
}

// designa un template single alternativo per il link alt sopra
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;
}

Dopo alcuni giorni passati a guardarlo (e aver provato alcune varianti senza successo), non riesco a individuare il problema, ma devo aver trascurato qualcosa.

0
Tutte le risposte alla domanda 3
1

Per visualizzare template diversi per lo stesso tipo di post creerei 2 link differenti, verificherei su quale link mi trovo attualmente e deciderei quale template caricare.

Esempio funzionante:

/**
 * Registra il post type per gli eventi
 *
 * La registrazione del post type eventi aggiungerà una struttura di permalink come event/([^/]+)/?$
 */
function wpse_288345_register_event_post_type() {

    $labels = array(
        'name' => __( 'Eventi' ),
        'singular_name' => __( 'Evento' ),
        'add_new' => __( 'Aggiungi nuovo' ),
        'add_new_item' => __( 'Aggiungi nuovo' ),
        'edit_item' => __( 'Modifica' ),
        'new_item' => __( 'Nuovo' ),
        'view_item' => __( 'Visualizza' ),
        'search_items' => __( 'Cerca' ),
        'not_found' => __( 'Non trovato' ),
        'not_found_in_trash' => __( 'Nessun Evento trovato nel cestino' ),
        'parent_item_colon' => __( 'Genitore' ),
        'menu_name' => __( 'Eventi' ),

    );

    $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' );

/**
 * Aggiunge regole di rewrite personalizzate per il post type eventi.
 *
 * Ricordati di svuotare le regole di rewrite per applicare le modifiche.
 */
function wpse_288345_add_event_rewrite_rules() {

    /**
     * Regole di rewrite personalizzate per un post type.
     * 
     * Sapremo su quale url ci troviamo tramite i parametri $_GET 'performers' e 'summary'. Che aggiungeremo
     * alle query vars pubbliche per ottenerli in modo 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');

/**
 * Aggiunge le query vars personalizzate 'performers' e 'summary' per gli eventi.
 */
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 quale template caricare
 */
function wpse_288345_load_performers_or_summary_template( $template ) {

    // Ottieni le query vars pubbliche
    $performers = (int) get_query_var( 'performers', 0 );
    $summary    = (int) get_query_var( 'summary', 0 );

    // Se performer = 1 allora siamo sul link event/performers
    if( $performers === 1 ) {
        $template = locate_template( array( 'single-event-performers.php' ) );
    }

    // Se summary = 1 allora siamo sul link event/summary
    if( $summary === 1 ) {
        $template = locate_template( array( 'single-event-summary.php' ) );
    }

    if($template == '') {
        throw new \Exception('Nessun template trovato');
    }

    return $template;
}

add_filter( 'template_include', 'wpse_288345_load_performers_or_summary_template' );
12 dic 2017 09:58:43
Commenti

Ho trovato una soluzione alternativa semplice, ma segnerò questa come risposta perché risponde più da vicino alla mia domanda. La testerò e farò sapere se funziona. Sembra molto promettente.

Ray Gulick Ray Gulick
12 dic 2017 15:11:12
0

Ecco l'approccio alternativo che ho fatto funzionare, utilizzando un parametro GET e istruzioni condizionali.

  1. Sulla pagina di elenco alternativa, ho aggiunto '?template=kiosk' ai permalink.

  2. Nel template dei singoli elementi (single-plans.php) ho aggiunto il seguente codice all'inizio del template (e naturalmente 'endif' alla fine del template):

    $kiosk = $_GET['template'];
    if(isset($kiosk)) :
  3. Poi, throughout il template, ho creato delle istruzioni condizionali basate sulla presenza o meno del parametro, per visualizzare il contenuto in modo appropriato:

    if(isset($kiosk)) { 
        // mostra versione kiosk
        } else {
        // mostra versione standard
        }

12 dic 2017 15:32:39
0

Stavo provando quasi esattamente lo stesso codice, e non funzionava. C'è solo una modifica da apportare per farlo funzionare completamente. Basta aggiungere locate_template a una riga.

Cambiare

if ( $alt === 'alt' ) $template = 'single-kioskplans.php';

in

if ( $alt === 'alt' ) $template = locate_template('single-kioskplans.php');

Il codice completo sarà così:

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;
}

//designa un modello single alternativo per il link alt sopra
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;
}
30 ott 2020 21:03:35