Problema con Custom Post Type como Página de Inicio
Escribí un plugin que utiliza Custom Post Types para crear una serie de páginas. Tengo el código que añade el CPT al menú desplegable de "Lectura" y funciona muy bien.
Aquí está...
add_filter( 'get_pages', 'add_wpwebinar_front' );
function add_wpwebinar_front( $pages ) {
$my_wpwebinar_pages = new WP_Query( array( 'post_type' => 'wpwebinar' ) );
if ( $my_wpwebinar_pages->post_count > 0 ) {
$pages = array_merge( $pages, $my_wpwebinar_pages->posts );
}
return $pages;
}
El código funciona pero si seleccionas un Custom Post Type como página de inicio, redirige a la página real del CPT. Ejemplo... dominio.com redirigiría a dominio.com/slug/nombredelapagina
Para solucionar esto, encontré este código que añadí...
function enable_front_page_stacks( $query ){
global $post, $wp_query;
if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
$query->set('post_type', 'wpwebinar');
}
add_action( 'pre_get_posts', 'enable_front_page_stacks' );
Esto mantiene el Custom Post Type como página principal. Pero... tengo algunos problemas.
- Si seleccionas la opción por defecto de mostrar las últimas entradas, FUNCIONA BIEN.
- Si seleccionas una página de Custom Post Type como página de inicio, FUNCIONA BIEN.
El problema ocurre cuando seleccionas una PÁGINA NORMAL como página de inicio. Hereda la plantilla del Custom Post Type y no muestra el contenido de la página, por supuesto, porque no hay código para ello.
Estoy seguro de que la solución es simple, pero no tengo idea de qué cambiar.
¿Alguien tiene ideas? Sería muy apreciado.

El error está en el código que agregaste:
function enable_front_page_stacks( $query ){
global $post, $wp_query;
if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
$query->set('post_type', 'wpwebinar');
}
Específicamente en $query->set()
. Esta llamada establecerá específicamente el tipo de publicación como "wpwebinar" si no está configurado explícitamente como otra cosa. Como resultado, al acceder a una página normal, forzará a asumir "wpwebinar" y cargará la plantilla del tipo de publicación personalizado.
En cambio, modifica tu función así:
function enable_front_page_stacks( $query ){
if(( ! isset($query->query_vars['post_type']) || '' == $query->query_vars['post_type']) && 0 != $query->query_vars['page_id'])
$query->query_vars['post_type'] = array( 'page', 'wpwebinar' );
}
Esta era la función original enable_front_page_stacks()
que escribí, pero usando "wpwebinar" en lugar de "stack" como el tipo de publicación personalizado adicional.
Referenciar un archivo de plantilla desde un plugin
Por lo general, las mejores prácticas incluyen registrar un CPT (Custom Post Type) con un plugin y dejar las plantillas del CPT en manos del tema. Esto suele funcionar mejor con el estilo y permite al usuario final control total sobre el diseño del sitio. Sin embargo, existen raras situaciones donde tiene sentido especificar la plantilla del CPT en el propio plugin.
Para manejar esto, necesitas engancharte a la función get_single_template()
del núcleo para indicarle dónde obtener el archivo. Este es el patrón típico de solicitud:
template-loader.php
--> if ( is_single() ) $template = get_single_template()
-- --> template.php -> get_single_template()
-- -- --> $templates[] = array( 'single.php', 'single-{post_type}.php' );
-- -- --> return get_query_template( 'single', $templates )
-- -- -- --> template.php -> get_query_template( $type, $templates )
-- -- -- -- --> if ( empty($templates) ) $templates = array( '{$type}.php' );
-- -- -- -- --> return apply_filters( "{$type}_template", locate_template( $templates ) )
Para registrar la plantilla de tu CPT alojada en el plugin, necesitas engancharte a este filtro y especificar su ubicación.
function load_plugin_cpt_template( $path ) {
$path = dirname(__FILE__) . '/single-wpwebinar.php';
return $path;
}
add_filter( 'wpwebinar_template', 'load_plugin_cpt_template' );
Uso dirname( __FILE__ )
arriba basado en la suposición de que tu plantilla de CPT está al mismo nivel que el archivo con esta función. Si no es así, ajusta la ruta de inclusión según corresponda. Ten en cuenta que esta función anulará cualquier archivo single-wpwebinar.php
especificado por el tema.
Como medida de seguridad, puedes verificar el valor pasado de $path
para ver si estamos usando single.php
o una anulación especificada por el tema, pero eso es un ejercicio que dejo en tus manos.
También hay un tutorial más completo publicado en mi sitio: http://jumping-duck.com/tutorial/theme-ready-custom-post-types-in-wordpress/.

EAMann, lo intenté pero el problema sería al revés, es decir, la página del CPT ahora está usando la plantilla de página estándar y NO la plantilla del CPT. Así que terminas con una página que básicamente solo muestra el título. Por eso usé una versión modificada de tu código original usando $query->set. Al usar $query->set, la página usa la plantilla del CPT, pero una página real configurada en "Lectura" adopta la plantilla del CPT. ¿Entiendes mi punto?

Necesitaría ver cómo son tus plantillas, porque tu CPT debería usar single-wpwebinar.php
como plantilla si estás usando el mismo código.

Estoy usando 'template_redirect' para cambiar la ubicación de la página single-wpwebinar.php. Tal vez eso influya en esto. El problema es que la página del CPT no está implementando la plantilla de CPT que creé. He intentado mover el single-wp-webinar.php a la raíz del tema para probar y eliminar el template-redirect, pero sigo obteniendo los mismos resultados. El CPT sigue heredando la plantilla de página normal.

Si tu CPT está registrado como wpwebinar
debes usar la plantilla single-wpwebinar.php
en el tema. single-wp-webinar.php
no funcionará. Y si estás sobrescribiendo el tema con un plugin, diría que estás haciendo algo mal... pero eso es una discusión más larga. Una ruta más fácil aquí sería construir tu CPT, crear una plantilla de página para el CPT, luego registrar un shortcode que pueda usarse en una página estándar para mostrar tu CPT.

El single-wp-webinar.php fue un error tipográfico. Estoy usando el single-wpwebinar.php. El punto central es que EL CPT ES UN PLUGIN. Así que el single-wpwebinar.php está en la carpeta de plugins, por eso uso template_redirect para obtener la ubicación correcta de la plantilla.

Si absolutamente debes colocar tu archivo de plantilla en el plugin en lugar del tema... mira mi actualización para ver cómo hacerlo.
