¿Cómo se usa un CPT como página de inicio predeterminada?

20

Tengo un cliente cuyo sitio hará un uso intensivo de los tipos de publicaciones personalizadas para configurar su sitio. Pero estoy entre una roca y un lugar difícil para la página de inicio solicitada.

En realidad, la página de inicio será una pila de "páginas" específicas dentro de WordPress. Básicamente, habrá páginas para: Introducción , Blog , Acerca de nosotros , Portafolio y Contáctenos . Todos se apilarán uno encima del otro para que pueda desplazarse de una página a otra.

Mi primer instinto fue simplemente usar una página (llamada Inicio ) e incrustar un código corto que acepta slugs de página y genera el orden correcto (es decir [pageOrder]intro, blog, about-us, portfolio, contact-us[/pageOrder]). La página usaría una plantilla de página personalizada para diseñar cosas, controlar el bucle y agregar navegación al lado izquierdo de la página. Pero todo eso parece extraño.

Mi solución ideal sería crear un tipo de publicación personalizado (llamado Pila ) que permita al usuario final colocar las páginas con arrastrar y soltar y hacer que el CPT se encargue del diseño y la navegación y demás.

El problema con mi solución ideal es la configuración. WordPress le permite seleccionar una página para la página de inicio predeterminada del sitio. Pero está vinculado a un tipo de página de publicación , y no estoy seguro de dónde conectarlo para modificarlo para que los usuarios también puedan seleccionar una Pila como la página de inicio predeterminada.

Entonces, ¿dónde me conecto para agregar un CPT al menú desplegable de páginas disponibles para la página de inicio predeterminada?

EAMann
fuente

Respuestas:

11

Gracias a @toscho por la útil respuesta, pero me pareció un poco difícil, así que busqué un poco y descubrí que podía agregar un filtro en su lugar:

function wpa18013_add_pages_to_dropdown( $pages, $r ){
    if('page_on_front' == $r['name']){
        $args = array(
            'post_type' => 'stack'
        );
        $stacks = get_posts($args);
        $pages = array_merge($pages, $stacks);
    }

    return $pages;
}
add_filter( 'get_pages', 'wpa18013_add_pages_to_dropdown', 10, 2 );

Actualizar

Después de agregar el código anterior, pude usar un tipo de publicación personalizada como página de inicio, pero WordPress redirigió los enlaces permanentes porque no era un tipo de publicación de "página". Entonces http://localhost/testredirigiría a http://localhost/test/stacks/home-stack, que no era lo que quería.

Sin embargo, agregar esta acción solucionó eso y consulta mi tipo de publicación personalizada junto con las páginas de la página de inicio:

function enable_front_page_stacks( $query ){
    if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
        $query->query_vars['post_type'] = array( 'page', 'stack' );
}
add_action( 'pre_get_posts', 'enable_front_page_stacks' );
EAMann
fuente
También jugué con dicho filtro, pero tiene que estar restringido a la consulta de la página principal. Y luego me golpearon algunos comportamientos / errores extraños: obtuve solo 404s. De todos modos +1. :)
fuxia
Buena atrapada. El condicional adicional dentro de la función (asegúrese de post_typeque no esté configurado y que page_idno sea 0) evita todos los 404. Ahora puedo ejecutar consultas para todas mis publicaciones personalizadas, todas mis publicaciones y todas mis páginas sin ninguna interferencia.
EAMann
@EAmann ¡Gracias por el código! Funciona como debería, aunque cambia el título de la portada a Título de publicación | Nombre de la página de inicio, ¿se puede cambiar para que sea solo el nombre de la página de inicio, de alguna manera?
INT
Esto no funciona en absoluto ... advertencias / errores del servidor: Falta el argumento 2 para wpa18013_add_pages_to_dropdown () y la variable Indefinida: r
Dameer
8

¿Tal vez sea así? Versión refinada de mi solución anterior .

add_filter( 'wp_dropdown_pages', 'add_cpt_to_front_page_dropdown', 10, 1 );


/**
 * Adds CPTs to the list of available pages for a static front page.
 *
 * @param  string $select Existing select list.
 * @return string
 */
function add_cpt_to_front_page_dropdown( $select )
{
    if ( FALSE === strpos( $select, '<select name="page_on_front"' ) )
    {
        return $select;
    }

    $cpt_posts = get_posts(
        array(
            'post_type'      => 'YOUR_POST_TYPE'
        ,   'nopaging'       => TRUE
        ,   'numberposts'    => -1
        ,   'order'          => 'ASC'
        ,   'orderby'        => 'title'
        ,   'posts_per_page' => -1
        )
    );

    if ( ! $cpt_posts ) // no posts found.
    {
        return $select;
    }

    $current = get_option( 'page_on_front', 0 );

    $options = walk_page_dropdown_tree(
        $cpt_posts
    ,   0
    ,    array(
            'depth'                 => 0
         ,  'child_of'              => 0
         ,  'selected'              => $current
         ,  'echo'                  => 0
         ,  'name'                  => 'page_on_front'
         ,  'id'                    => ''
         ,  'show_option_none'      => ''
         ,  'show_option_no_change' => ''
         ,  'option_none_value'     => ''
        )
    );

    return str_replace( '</select>', $options . '</select>', $select );
}
fuxia
fuente
¿Esto es solo para seleccionar el tipo de publicación personalizada, pero eso no hace que muestre ese tipo de publicación personalizada como portada? ¿O me estoy perdiendo algo?
Hameedullah Khan
@Hameedullah: una vez que lo selecciona, WordPress actualiza una opción que marca qué página se supone que se utilizará para la página principal. Luego, cuando un usuario visita la página principal, WordPress lee la misma opción desde la base de datos.
EAMann
@Hameedullah Khan Tienes razón. Esto funcionó antes de 3.1, ahora soy redirigido al enlace permanente de la publicación, y obtengo un 404. Extraño. Desearía tener tiempo para esto. :(
fuxia
5

¿Por qué no simplemente crear un front-page.phparchivo de plantilla, que utiliza una consulta / bucle normal o (si se configura una opción de tema personalizado para mostrar el CPT en la página principal), genera una consulta / bucle personalizado, basado en el CPT?

El problema es que tendrías que crear una opción de tema separada para controlar la salida de la página principal, al mismo tiempo que se indica a los usuarios que configuren la página principal en página estática.

Para facilitar las cosas, puede conectar su opción de Tema a la configuración de lectura, utilizando el grupo de opciones "Lectura" en su llamada a register_settingtravés de la API de Configuración, para que se muestre con las opciones existentes de la Página Principal.

Chip Bennett
fuente
Me gustan las soluciones simples y Chip, creo que la tuya es la mejor. Wordpress permite plantillas personalizadas para la página de inicio codex.wordpress.org/Template_Hierarchy#Home_Page_display y luego uno puede hacer lo que quiera dentro de eso.
Anmari
Esta es la solución más fácil de mantener y sencilla. El front-page.phpse selecciona automáticamente porque es parte de la jerarquía de plantillas de WordPress. No es necesario recordar por qué sucede esto (o necesita marcarlo para la próxima persona).
Odys
2

Creo que algo puede haber cambiado desde que EAMann escribió su actualización en 2011, y la función wpa18013_add_pages_to_dropdown () que suministra ya no funciona. Como se menciona en un comentario de Dameer, esta función actualmente (diciembre de 2013) arroja un error "Falta el argumento 2 para wpa18013_add_pages_to_dropdown ()"

La solución, para mí de todos modos, fue reescribir la función sin ese segundo parámetro, o verificar su contenido. El bloque completo de código se convierte en:

function add_unbox_tabs_to_dropdown( $pages ){
    $args = array(
        'post_type' => 'unbox_tabs'
    );
    $items = get_posts($args);
    $pages = array_merge($pages, $items);

    return $pages;
}
add_filter( 'get_pages', 'add_unbox_tabs_to_dropdown' );

function enable_front_page_unbox_tabs( $query ){
    if('' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'])
        $query->query_vars['post_type'] = array( 'page', 'unbox_tabs' );
}
add_action( 'pre_get_posts', 'enable_front_page_unbox_tabs' );

Tenga en cuenta que en el ejemplo anterior, el tipo de publicación personalizada que estoy agregando es "unbox_tabs" en lugar de "stack".

Matthew Bernhardt
fuente
1

Estoy usando esta tecnica para incluir una plantilla de un complemento. Entonces, la solución de @ ChipBennett no se aplica.

Para agregar los CPT ( ) del complemento en la lista de páginas estáticas, modifiqué la solución de @ EAMann de la siguiente manera: 'hierarchical' => 'false'

add_action( 'admin_head-options-reading.php', 'wpse_18013_modify_front_pages_dropdown' );
add_action( 'pre_get_posts', 'wpse_18013_enable_front_page_stacks' );

function wpse_18013_modify_front_pages_dropdown()
{
    // Filtering /wp-includes/post-templates.php#L780
    add_filter( 'get_pages', 'wpse_18013_add_cpt_to_pages_on_front' );
}

function wpse_18013_add_cpt_to_pages_on_front( $r )
{
    $args = array(
        'post_type' => 'stack'
    );
    $stacks = get_posts( $args );
    $r = array_merge( $r, $stacks );

    return $r;
}

function wpse_18013_enable_front_page_stacks( $query )
{
    if( '' == $query->query_vars['post_type'] && 0 != $query->query_vars['page_id'] )
        $query->query_vars['post_type'] = array( 'page', 'stack' );
}

Referencia central v3.4.2:
ligera diferencia de números de línea en 3.5 RC3, pero el código sigue siendo el mismo

/**
 * wp-admin/options-reading.php#L96
 * Happens inside a <li><label>-</label></li>
 */
    wp_dropdown_pages( array( 
                'name' => 'page_on_front'
            ,   'echo' => 0
            ,   'show_option_none' => __( '&mdash; Select &mdash;' )
            ,   'option_none_value' => '0'
            ,   'selected' => get_option( 'page_on_front' ) 
        ) 
    )

/**
  * wp-includes/post-template.php#L768
  */
function wp_dropdown_pages($args = '') {
    $defaults = array( /* defaults array */ );    
    $r = wp_parse_args( $args, $defaults );
    extract( $r, EXTR_SKIP );  
    $pages = get_pages( $r );
brasofilo
fuente