Mostrar el mismo tipo de publicación personalizada en 2 plantillas single diferentes

11 dic 2017, 18:33:30
Vistas: 1.32K
Votos: 1

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.

0
Todas las respuestas a la pregunta 3
1

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' );
12 dic 2017 09:58:43
Comentarios

Encontré una solución alternativa simple, pero voy a marcar esta como la respuesta porque responde más de cerca a mi pregunta. También probaré esto e informaré si funciona. Parece muy prometedor.

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

Aquí está el enfoque alternativo que logré hacer funcionar, utilizando un parámetro GET y declaraciones condicionales.

  1. En la página de listado alternativo, agregué '?template=kiosk' a los enlaces permanentes.

  2. 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)) :
  3. 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
        }

12 dic 2017 15:32:39
0

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;
}
30 oct 2020 21:03:35