WordPress : Comment définir une publication de type message personnalisé en tant que page d’accueil statique ?

Publié par Jean-Michel le

J’écris mon thème personnalisé à partir de zéro et j’ai un type de message personnalisé ‘my_frontpage’ et je souhaite déclarer l’un de ses messages comme page d’accueil. Je veux le faire via l’administrateur, donc ajoutez simplement mon cpt à la case de sélection de la page d’accueil dans Apparence >> Personnaliser >> Page d’accueil statique .

Cette question a été abordée à plusieurs reprises sur Internet. Cependant, je n’ai pas pu trouver comment des instructions qui expliquent en détail toutes les étapes pour atteindre cet objectif.

Jusqu’à présent, je comprends que j’ai besoin d’utiliser une sorte de crochet pour élargir le choix de « pages » de première page disponibles avec des messages de mon cpt. Mais quel crochet utiliser ? Je ne saurais même pas si je dois utiliser une action ou un hook de filtre ? Alors, quelqu’un pourrait-il me guider à travers ce problème en termes simples ?

Le résultat le plus proche que j’ai pu trouver était cette question. Cependant, je ne suis pas encore en mesure de comprendre pleinement ce qui s’y passe…

Solution n°1 trouvée

While Pieter solved the issue elegant and comprehensively with no doubt, I finally went with another solution, which I want to share here, too. Maybe some folks are facing similiar issues in the time to come.

For custom post type definition as described in my question I used a plugin called Pods. As the plugin devs and community are likely to handle custom post types regularly, I thought it might be helpful to ask my question in their support channel, too.

C’était un gars très serviable de l’équipe de développement de Pods qui m’a indiqué la direction avec laquelle j’ai finalement suivi. Ainsi, au lieu de définir un type de publication personnalisé dans le but de créer une page d’accueil statique très individuelle, il a recommandé d’ajouter plutôt des champs personnalisés à une page standard, qui devrait devenir la page d’accueil. C’est ce que j’ai fait pour atteindre mon objectif et c’est ce que je recommande également aux autres utilisateurs.

Du point de vue de la modélisation des données, il n’y a aucune raison de définir un type de données complet ou, disons, une classe, si vous ne souhaitez l’appliquer qu’à un seul élément – dans mon cas, une seule page d’accueil. J’ai utilisé un autre plugin appelé Advanced Custom Fields, car cela permet des types de données plus avancés pour vos champs personnalisés que ceux proposés par WordPress. Vous pouvez également ajouter vos champs personnalisés via functions.php. J’espère que cela pourra aider.

Solution n°2 trouvée

I had time to look at your issue and the options-reading.php page which is the template used to render the reading settings page in backend.

There are unfortunately no filters to filter or add custom posts as sticky posts in a selectable dropdown. There are two hidden filters though which we can use, they are

  • wp_dropdown_pages inside the wp_dropdown_pages() function which is used by the dropdown which display the list of pages which can be set as static front page

  • get_pages inside the get_pages() function which is the function responsible to return the pages which is used by wp_dropdown_pages()

IMHO, I think get_pages here is a better option. This way we will let wp_dropdown_pages() to take care of all the markup. We need to take care here though when we use the get_pages filter

  • Nous devrons nous assurer de ne cibler que la zone d’administration et en particulier la page des paramètres de lecture, sinon nous modifierons toute fonction/page qui utilise la get_pages()fonction

Vous devez décider si vous auriez besoin de pages à afficher avec les messages de type de publication personnalisés ou si vous avez simplement besoin des types de publication personnalisés

Vous pouvez essayer ce qui suit :

add_filter( 'get_pages', function ( $pages, $args )
{
    // First make sure this is an admin page, if not, bail
    if ( !is_admin() )
        return $pages;

    // Make sure that we are on the reading settings page, if not, bail
    global $pagenow;
    if ( 'options-reading.php' !== $pagenow )
        return $pages;

    // Remove the filter to avoid infinite loop
    remove_filter( current_filter(), __FUNCTION__ );

    $args = [
        'post_type'      => 'my_frontpage',
        'posts_per_page' => -1
    ];
    // Get the post type posts with get_posts to allow non hierarchical post types
    $new_pages = get_posts( $args );

    /**
     * You need to decide if you want to add custom post type posts to the pages
     * already in the dropdown, or just want the custom post type posts in
     * the dropdown. I will handle both, just remove what is not needed
     */
    // If we only need custom post types
    $pages = $new_pages;

    // If we need to add custom post type posts to the pages
    // $pages = array_merge( $new_pages, $pages );

    return $pages;
}, 10, 2 );

Vous devriez maintenant voir vos messages de type de publication personnalisés dans la liste déroulante. Notez que ce code affectera également la liste déroulante de la page de blog.

Pour éviter cela, vous pouvez utiliser un compteur statique pour compter le nombre de fois où le filtre a été exécuté, puis le renflouer juste avant que le filtre ne soit appliqué à la liste déroulante de la page de blog. Le filtre s’exécutera au total 3 fois car get_pages()s’exécute 3 fois :

  • d’abord pour vérifier si nous avons réellement des pages à définir comme une page d’accueil statique.

  • la deuxième exécution sera à l’intérieur wp_dropdown_pages()qui est utilisée par la liste déroulante statique de la page d’accueil

  • la dernière exécution sera à l’intérieur wp_dropdown_pages()qui est utilisée par la liste déroulante de la page de blog

Donc, sur cette base, nous pouvons essayer

add_filter( 'get_pages', function ( $pages, $args )
{
    // First make sure this is an admin page, if not, bail
    if ( !is_admin() )
        return $pages;

    // Make sure that we are on the reading settings page, if not, bail
    global $pagenow;
    if ( 'options-reading.php' !== $pagenow )
        return $pages;

    // Remove the filter to avoid infinite loop
    remove_filter( current_filter(), __FUNCTION__ );

    // Setup our static counter
    static $counter = 0;

    // Bail on the third run all runs after this. The third run will be 2
    if ( 2 <= $counter )
        return $pages;

    // Update our counter
    $counter++;

    $args = [
        'post_type'      => 'my_frontpage',
        'posts_per_page' => -1
    ];
    // Get the post type posts with get_posts to allow non hierarchical post types
    $new_pages = get_posts( $args );

    /**
     * You need to decide if you want to add custom post type posts to the pages
     * already in the dropdown, or just want the custom post type posts in
     * the dropdown. I will handle both, just remove what is not needed
     */
    // If we only need custom post types
    $pages = $new_pages;

    // If we need to add custom post type posts to the pages
    // $pages = array_merge( $new_pages, $pages );

    return $pages;
}, 10, 2 );

Si vous visitez le front-end et visitez la page d’accueil, vous constaterez qu’il redirigera vers la page de publication unique. En effet, par défaut, la requête principale sur une page d’accueil statique est définie pour interroger le pagetype de publication. Cela provoque le retour d’un 404, redirect_canonical()puis la redirection vers la page de publication unique. C’est facile à résoudre, tout ce que nous devons faire est d’ajuster la requête principale sur la page d’accueil statique.

add_action( 'pre_get_posts', function ( $q )
{
    if (    !is_admin() // Only target the front end
         && $q->is_main_query() // Only target the main query
         && 'page' === get_option( 'show_on_front' ) // Only target the static front page
    ) {
        $q->set( 'post_type', 'my_frontpage' );
    }
});

Votre page d’accueil statique s’affichera désormais correctement.

Il ne vous reste plus qu’à définir un modèle. Vous pouvez simplement créer un front-page.php, WordPress l’utilisera automatiquement

Solution n°3 trouvée

Eh bien, il existe également un moyen supplémentaire d’éviter d’utiliser un modèle de page et de laisser WordPress charger la page d’accueil en utilisant le bon modèle de type de publication. Cela permet d’éviter la duplication de code si vous souhaitez que la page d’accueil ait la même apparence que le message unique lui-même :

add_filter( 'template_include', 'add_front_page_template_path', 10, 1);

function add_front_page_template_path( $template_path ) {
    if (
        is_front_page()
        && get_option( 'show_on_front' ) == 'page'
        && ( $post_id = get_option( 'page_on_front' ) )
        && ( $post_type = get_post_type( $post_id ) ) != 'page'
    ) {
        $_template_path = get_single_template( $post_type );

        /* In case there’s no template */
        $template_path = ( $template_path == '' ) ? $template_path : $_template_path;
    }

    return $template_path;
}

Catégories : Wordpress

Jean-Michel

Jean-Michel est en charge de la partie blog du site. Il met en place la stratégie de contenu et répond aux questions fréquentes sur Wordpress.

0 commentaire

Laisser un commentaire

Avatar placeholder

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *