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

20

J'ai un client dont le site fera un usage intensif des types de publication personnalisés pour configurer son site. Mais je suis entre un rocher et un endroit difficile pour leur 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 afin que vous puissiez faire défiler d'une page à l'autre.

Mon premier réflexe a été d'utiliser simplement une page (appelée Home ) et d'incorporer un shortcode qui accepte les slugs de page et génère le bon ordre (ie [pageOrder]intro, blog, about-us, portfolio, contact-us[/pageOrder]). La page utiliserait un modèle de page personnalisé pour disposer les choses, contrôler la boucle et ajouter la navigation sur le côté gauche de la page. Mais tout cela semble maladroit.

Ma solution idéale serait de créer un type de publication personnalisé (appelé Stack ) qui permet à l'utilisateur final de positionner les pages par glisser-déposer et de laisser le CPT prendre en charge la mise en page et la navigation, etc.

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 il est lié à un type de page de publication , et je ne sais pas où le connecter pour le modifier afin que les utilisateurs puissent également sélectionner une pile comme page d'accueil par défaut.

Alors, où dois-je me connecter pour ajouter un CPT à la liste déroulante des pages disponibles pour la page d'accueil par défaut?

EAMann
la source

Réponses:

11

Merci à @toscho pour la réponse utile, mais cela m'a semblé un peu hack, alors j'ai fouillé un peu et j'ai compris que je pouvais 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 );

Mise à jour

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

L'ajout de cette action, cependant, a corrigé cela 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' );
EAMann
la source
J'ai également joué avec un tel filtre, mais il doit être limité à la requête en première page. Et puis j'ai été battu par des comportements / bugs étranges: je n'ai eu que 404s. Quoi qu'il en soit +1. :)
fuxia
Bonne prise. Le conditionnel supplémentaire à l'intérieur de la fonction (assurez-vous qu'il post_typen'est pas déjà défini et que ce page_idn'est pas 0) empêche tous les 404. Je peux maintenant exécuter des requêtes pour tous mes articles personnalisés, tous mes articles et toutes mes pages sans aucune interférence.
EAMann
@EAmann Merci pour le code! Il fonctionne comme il se doit, bien qu'il change le titre de la première page en Titre du message | Le nom de la page d'accueil, peut-il être changé pour être simplement le nom de la page d'accueil, d'une manière ou d'une autre?
INT
Cela ne fonctionne pas du tout ... avertissements / erreurs du serveur: argument manquant 2 pour wpa18013_add_pages_to_dropdown () et variable non
Dameer
8

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 );
}
fuxia
la source
C'est seulement pour sélectionner le type de publication personnalisé, mais cela ne le fait pas afficher ce type de publication personnalisé en première page? ou est-ce que je manque quelque chose?
Hameedullah Khan
@Hameedullah - Une fois que vous l'avez sélectionné, WordPress met à jour une option qui marque quelle page est censée être utilisée pour la première page. Ensuite, lorsqu'un utilisateur visite la page d'accueil, WordPress lit la même option dans la base de données.
EAMann
@Hameedullah Khan Vous avez raison. Cela fonctionnait avant 3.1, maintenant je suis redirigé vers le permalien du post - et j'obtiens un 404. Étrange. J'aimerais avoir le temps pour ça. :(
fuxia
5

Pourquoi ne pas simplement créer un front-page.phpfichier modèle, qui utilise soit une requête / boucle normale, soit (si une option de thème personnalisée 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 est que vous devrez créer une option de thème distincte pour contrôler la sortie de la page d'accueil, tout en demandant aux utilisateurs de définir la page d'accueil sur la page statique.

Pour faciliter les choses, vous pouvez connecter votre option Thème à la lecture des paramètres, en utilisant le groupe d'options "Lecture" dans votre appel à register_settingvia l'API Paramètres, afin qu'il s'affiche avec les options de la page d'accueil existantes.

Chip Bennett
la source
J'aime les solutions simples et Chip, je pense que la vôtre est la meilleure. Wordpress permet des modèles personnalisés pour la page d'accueil codex.wordpress.org/Template_Hierarchy#Home_Page_display et ensuite on peut faire ce qu'on veut à l'intérieur.
anmari
Il s'agit de la solution la plus simple et la plus facile à maintenir. Le front-page.phpest sélectionné automatiquement car fait partie de la hiérarchie des modèles WordPress. Pas besoin de se rappeler pourquoi cela se produit (ou besoin de le noter pour la prochaine personne).
Odys
2

Je pense que quelque chose a peut-être changé depuis que EAMann a écrit sa mise à jour en 2011, et 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 manquant 2 pour wpa18013_add_pages_to_dropdown ()"

La solution, pour moi en tout cas, était de 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 "stack".

Matthew Bernhardt
la source
1

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

Pour ajouter les CPT ( ) du plugin dans la liste des pages statiques, j'ai modifié la solution de @ EAMann comme suit: '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' );
}

Référence de base 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 );
brasofilo
la source