web-dev-qa-db-fra.com

Comment utilisez-vous un CPT comme page d'accueil par défaut?

J'ai un client dont le site fera un usage intensif de types de publication personnalisés pour configurer son site. Mais je suis entre le marteau et l'enclume pour la page d'accueil demandée.

En réalité, la page d'accueil sera une pile de "pages" spécifiques dans WordPress. Fondamentalement, il y aura des pages pour: Intro, Blog, À propos de nous, Portfolio, et Contactez-nous . Ils seront tous empilés les uns sur les autres pour que vous puissiez faire défiler une page à une autre.

Mon premier réflexe a été d’utiliser une page (appelée Home) et d’incorporer un shortcode qui accepte les slug de page et affiche le bon ordre (c.-à-d. [pageOrder]intro, blog, about-us, portfolio, contact-us[/pageOrder]). La page utiliserait un modèle de page personnalisé pour disposer les éléments, contrôler la boucle et ajouter une navigation sur le côté gauche de la page. Mais cela semble tout klunky.

Mon idéal solution consisterait à créer un type de publication personnalisé (appelé pile) permettant à l'utilisateur final de positionner les pages avec un glisser-déposer et de laisser le CPT s'occuper de la mise en page et de la navigation. et autres choses de ce genre.

Le problème avec ma solution idéale est les paramètres. WordPress vous permet de sélectionner une page pour la page d'accueil par défaut du site. Mais cela est lié à un type de message de {page} _, et je ne sais pas trop à quel branchement il faut modifier pour que les utilisateurs puissent également sélectionner un Stack comme page d'accueil par défaut.

Alors, où puis-je me connecter pour ajouter un CPT au menu déroulant des pages disponibles pour la page d'accueil par défaut?

20
EAMann

Merci à @toscho pour la réponse utile, mais cela me paraissait un peu fictif, alors je me suis un peu fourré et j'ai pensé pouvoir ajouter un filtre à la place:

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

Mettre à jour

Après avoir ajouté le code ci-dessus, j'ai effectivement pu utiliser un type de publication personnalisé comme page d'accueil, mais WordPress redirigerait les liens permanents, car ce n'était pas un type de publication "page". Donc, http://localhost/test redirigerait vers http://localhost/test/stacks/home-stack, ce qui n'était pas ce que je voulais.

L'ajout de cette action, cependant, a résolu ce problème et interroge mon type de publication personnalisé ainsi que les pages de la page d'accueil:

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' );
11
EAMann

Peut-être? Version raffinée de ma solution précédente .

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 );
}
8
fuxia

Pourquoi ne pas simplement créer un fichier modèle front-page.php, qui utilise une requête/boucle normale ou (si une option de thème personnalisé est définie pour afficher le CPT sur la page d'accueil), génère une requête/boucle personnalisée, basée sur le CPT?

Le problème ici est que vous devez créer une option de thème distincte pour contrôler la sortie de la page de garde, tout en demandant aux utilisateurs de définir Front page sur une page statique.

Pour simplifier les choses, vous pouvez associer votre option Thème à la lecture des paramètres, à l'aide du groupe d'options "Lecture" de votre appel à register_setting via l'API de configuration, afin qu'il s'affiche avec les options de page d'accueil existantes.

5
Chip Bennett

Je pense que quelque chose a changé depuis qu'EAMann a écrit sa mise à jour en 2011 et que la fonction wpa18013_add_pages_to_dropdown () qu'il fournit ne fonctionne plus. Comme mentionné dans un commentaire de Dameer, cette fonction génère actuellement (décembre 2013) une erreur "Argument 2 manquant pour wpa18013_add_pages_to_dropdown ()"

La solution, pour moi en tout cas, consistait à réécrire la fonction sans ce deuxième paramètre, ou la vérification de son contenu. Le bloc de code complet devient alors:

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

Veuillez noter que dans l'exemple ci-dessus, le type de publication personnalisé que j'ajoute est "unbox_tabs" plutôt que "pile".

2
Matthew Bernhardt

J'utilise cette technique pour inclure un modèle à partir d'un plugin. La solution de @ ChipBennett ne s'applique donc pas.

Pour ajouter les CPT ( 'hierarchical' => 'false' ) du plugin dans la liste des pages statiques, j’ai modifié la solution de @ EAMann comme suit:

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

référence centrale v3.4.2:
légère différence de numéros de ligne dans 3.5 RC3, mais le code reste le même

/**
 * 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 );
1
brasofilo