Modifier le modèle par défaut des articles dans Wordpress

Modifier le modèle par défaut des articles dans WordPress


Chaque thème WordPress est livrée avec des vues par défaut pour afficher vos articles. Vous remarquerez assez vite qu’en fonction du thème, ce n’est pas toujours le top et que ces pages statiques ne sont pas modifiables telles quelles. Alors comment procéder ?

Avant de commencer, veuillez noter que cet article nécessitera que vous sachiez ajouter et modifier des fichiers de votre site Internet par FTP et que vous ayez des bases de PHP.

Sur mon blog, toutes les pages sont issues de modèles personnalisés réalisés par mes soins. Il aurait bien sûr été possible d’utiliser par exemple le constructeur de Divi pour créer mes articles manuellement et de les copier pour conserver le même style pour chaque article.

Mais que se passe-t’il le jour où vous voulez rafraîchir le design de vos articles ? À nouveau, quelques solutions s’offrent à vous (les éléments globaux de Divi se mettent à jour dans toutes les pages automatiquement par exemple), mais pour une lourdeur et une complexité accrue.

Alors comment modifier le modèle d’article par défaut dans WordPress ? Il faudra pour cela :

  • Créer un thème enfant
  • Créer un nouveau fichier de modèle appelé single.php qui remplacera celui défini dans le thème parent

Cet article vous montrera également comment gérer des modèles différents par catégories d’articles et comment profiter de certains fonctionnalités de Divi pour faciliter la création de ces modèles.

Pour cet article, nous ne réinventerons pas la roue et nous travaillerons avec un thème existant (dans mon cas Divi donc, mais ce n’est pas impératif) à partir duquel nous créerons donc un thème enfant.

Il existe assez de tutoriaux sur le net pour vous guider dans la création d’un thème enfant, une fois cela fait, quelques explications !

Comment WordPress gère t’il l’affichage du contenu de votre site ?

Le principe

Lors d’une requête vers votre site, WordPress va analyser la demande, récupéré les paramètres afin de définir quel modèle utiliser pour afficher le contenu demandé.

WordPress va, en fonction du type de contenu à afficher (article, page, page d’accueil, recherche, etc.), rechercher dans le dossier du thème actif le ou les modèles à utiliser.

Pour se faire, une hiérarchie de modèle existe dans WordPress et le CMS va commencer par rechercher l’élément le plus précis, par exemple home.php pour l’accueil, puis remonter la hiérarchie s’il ne trouve pas ce fichier.

Lors de la création d’un thème (je ne parle pas de thème enfant, mais bien de thème), seul le fichier de base appelé index.php est obligatoire au bon fonctionnement du CMS. Aucune des autres page de la hiérarchie n’est obligatoire.

Donc si vous disposiez uniquement d’une page index.php, toutes les requêtes finiraient par afficher cette page comme modèle. Si vous décidez d’implémenter une page d’accueil en créant un fichier home.php, toutes les requêtes à la page d’accueil ou vers l’accueil de votre blog afficheront ce modèle. Et ainsi de suite.

Voici la hiérarchie des modèles dans WordPress pour mieux comprendre ce concept :

Structure hiérarchique des modèles dans WordPress

Thème enfant

Cependant, lorsque vous travaillez avec un thème enfant, une couche supplémentaire entre en jeu. L’idée d’un thème enfant est de pouvoir hériter de toutes les fonctionnalités d’un thème existant et d’ajouter ou remplacer modèles, fonctions, classes, etc. comme bon vous semble, sans pour autant toucher au code du thème parent.

Donc lors d’une requête vers la page d’accueil par exemple, WordPress va d’abord regarder dans le dossier de votre thème enfant si un fichier home.php existe, puis si un fichier index.php existe.

Si ce n’est pas le cas, il se rabattra sur le thème parent et effectuera la même recherche. À chaque fois, si le premier modèle n’existe pas, WordPress se rabattra sur le second et ainsi de suite.

Les modèles par type de requête

En complément à l’infographie ci-dessous, voici un récapitulatif des modèles recherchés par WordPress en fonction du type de contenu demandé.

Page d’accueil

  1. home.php
  2. index.php

Article de blog

  1. single.php
  2. index.php

Page

  1. Le modèle de page spécifié à l’édition de la page (si existant)
  2. page.php
  3. index.php

Catégorie

Une catégorie peut-être personnalisée de plusieurs manières, la plus simple est de créé un fichier php spécifique à la catégorie qui nous intéresse. Il suffit pour ça de récupérer l’id unique de la catégorie et de l’utiliser dans le nom du modèle.

Pour récupérer l’id d’une catégorie, rendez-vous sur la page des Catégories et survolez le nom de la catégorie dans la liste sur la droite :

Survolez une catégorie pour voir apparaître son ID dans l’attribut tag_ID affiché

Vous verrez alors apparaître le lien vers cette catégorie et dans ce lien se trouve l’attribut tag_ID, reprenez simplement la valeur indiquée. Dans cet exemple 20.

  1. category-20.php : Modèle personnalisé spécifique à une catégorie
  2. category.php
  3. archive.php
  4. index.php

Auteur d’articles

  1. author.php
  2. archive.php
  3. index.php

Page datée

Par exemple une page affichant les archives d’un mois donné.

  1. date.php
  2. archive.php
  3. index.php

Résultats de la recherche

  1. search.php
  2. index.php

Erreur 404

Page affichée lorsque la page demandée n’existe pas ou plus. J’en profite pour vous conseiller de ne pas l’oublier lors de la création de votre site. Une page 404 personnalisée donnera moins au visiteur l’impression d’un site « brisé » et il aura un meilleur sentiment de finition.

Jetez un œil à la mienne 🙂

  1. 404.php
  2. index.php

Fichiers joints

Il s’agit des fichiers images, audio, texte, etc.

  1. Modèle spécifique au type de fichier par exemple : image.php, video.php, audio.php, application.php ou tout préfixe de type MIME
  2. attachment.php
  3. single.php
  4. index.php

Le modèle d’article

Le concept à comprendre ici est qu’il suffit dès lors de créer un nouveau fichier dans votre thème enfant appelé single.php qui gérera l’affichage de vos articles et le tour est joué

Ce nouveau modèle aura préséance sur les autres et sera le modèle par défaut affichant tous les articles. Il s’occupera également d’afficher vos fichiers joints si vous effectués un lien vers ceux-ci, comme vous pouvez le voir dans la hiérarchie ci-dessus.

Si vous préférez ne modifier que les articles de blog sans toucher au modèle des fichiers joints, utilisez un modèle appelé single-post.php qui aura préséance sur single.php si on se réfère à l’infographie plus haut.

Dans le cas de cet article nous créerons un fichier single.php qui s’occupera de tout ça.

Mise en place

Avant propos

Afin de faciliter la gestion de ce fichier, l’idée est de partir d’un modèle existant. Vous pourriez essayer de créer votre modèle d’article de A à Z, mais vous risquez de vous compliquer la vie.

Pour vous assurer de réutiliser la même structure HTML (id, classes et types d’éléments) et de reprendre les classes PHP utilisées pour gérer l’affichage des articles, c’est le meilleure solution. D’autant que vous profiterez peut-être de fonctionnalités spécifiques au thème.

C’est également un très bon moyen d’apprendre le fonctionnement de ces modèles. Même si, vous le verrez par la suite, certains thèmes ont des modèles assez complexes, l’idée est de les simplifier pour faire ce dont vous avez besoin.

Créer votre fichier single.php

Commencez par vous connecter à votre FTP et naviguez jusqu’au dossier ou se trouve vos thèmes :

[Dossier de wordpress]/wp-content/themes

Là, jetez un œil au contenu du dossier de votre thème parent, par exemple Divi :

[Dossier de wordpress]/wp-content/themes/Divi

Dans ce dossier vous devriez trouver pas mal de fichiers qui définissent le fonctionnement du thème. Il est très peu probable que votre thème ne contienne pas déjà un fichier single.php pour présenter les articles de votre blog.

Dans Divi, le fichier single.php est bien présent à la racine du dossier

Donc rien de plus simple, il suffit de repérer ce fichier et de le copier (j’ai bien dit copier et non déplacer) dans le dossier de votre thème enfant :

[Dossier de wordpress]/wp-content/themes/[thème enfant]

Rappelez-vous, grâce au thème enfant, vous pouvez remplacer des fonctionnalités et modèles d’un thème parent sans pour autant l’endommager !

Modifier le fichier single.php

En ouvrant le fichier single.php, voici à peu prêt à quoi vous devez vous attendre (exemple ici d’un fichier Divi) :

<?php

get_header();

$show_default_title = get_post_meta( get_the_ID(), '_et_pb_show_title', true );

$is_page_builder_used = et_pb_is_pagebuilder_used( get_the_ID() );

?>

<div id="main-content">
        <?php
                if ( et_builder_is_product_tour_enabled() ):
                        // load fullwidth page in Product Tour mode
                        while ( have_posts() ): the_post(); ?>

                                <article id="post-<?php the_ID(); ?>" <?php post_class( 'et_pb_post' ); ?>>
                                        <div class="entry-content">
                                        <?php
                                                the_content();
                                        ?>
                                        </div> <!-- .entry-content -->

                                </article> <!-- .et_pb_post -->

                <?php endwhile;
                else:
        ?>
        <div class="container">
                <div id="content-area" class="clearfix">
                        <div id="left-area">
                        <?php while ( have_posts() ) : the_post(); ?>
                                <?php
                                /**
                                 * Fires before the title and post meta on single posts.
                                 *
                                 * @since 3.18.8
                                 */                                do_action( 'et_before_post' );
                                ?>
                                <article id="post-<?php the_ID(); ?>" <?php post_class( 'et_pb_post' ); ?>>
                                        <?php if ( ( 'off' !== $show_default_title &amp;&amp; $is_page_builder_used ) || ! $is_page_builder_used ) { ?>
                                                <div class="et_post_meta_wrapper">
                                                        <h1 class="entry-title"><?php the_title(); ?></h1>

                                                <?php
                                                        if ( ! post_password_required() ) :

                                                                et_divi_post_meta();

                                                                $thumb = '';

                                                                $width = (int) apply_filters( 'et_pb_index_blog_image_width', 1080 );

                                                                $height = (int) apply_filters( 'et_pb_index_blog_image_height', 675 );
                                                                $classtext = 'et_featured_image';
                                                                $titletext = get_the_title();
                                                                $thumbnail = get_thumbnail( $width, $height, $classtext, $titletext, $titletext, false, 'Blogimage' );
                                                                $thumb = $thumbnail["thumb"];

                                                                $post_format = et_pb_post_format();

                                                                if ( 'video' === $post_format &amp;&amp; false !== ( $first_video = et_get_first_video() ) ) {
                                                                        printf(
                                                                                '<div class="et_main_video_container">
                                                                                        %1$s
                                                                                </div>',
                                                                                et_core_esc_previously( $first_video )
                                                                        );
                                                                } else if ( ! in_array( $post_format, array( 'gallery', 'link', 'quote' ) ) &amp;&amp; 'on' === et_get_option( 'divi_thumbnails', 'on' ) &amp;&amp; '' !== $thumb ) {
                                                                        print_thumbnail( $thumb, $thumbnail["use_timthumb"], $titletext, $width, $height );
                                                                } else if ( 'gallery' === $post_format ) {
                                                                        et_pb_gallery_images();
                                                                }
                                                        ?>

                                                        <?php
                                                                $text_color_class = et_divi_get_post_text_color();

                                                                $inline_style = et_divi_get_post_bg_inline_style();

                                                                switch ( $post_format ) {
                                                                        case 'audio' :
                                                                                $audio_player = et_pb_get_audio_player();

                                                                                if ( $audio_player ) {
                                                                                        printf(
                                                                                                '<div class="et_audio_content%1$s"%2$s>
                                                                                                        %3$s
                                                                                                </div>',
                                                                                                esc_attr( $text_color_class ),
                                                                                                et_core_esc_previously( $inline_style ),
                                                                                                et_core_esc_previously( $audio_player )
                                                                                        );
                                                                                }

                                                                                break;
                                                                        case 'quote' :
                                                                                printf(
                                                                                        '<div class="et_quote_content%2$s"%3$s>
                                                                                                %1$s
                                                                                        </div> <!-- .et_quote_content -->',
                                                                                        et_core_esc_previously( et_get_blockquote_in_content() ),
                                                                                        esc_attr( $text_color_class ),
                                                                                        et_core_esc_previously( $inline_style )
                                                                                );

                                                                                break;
                                                                        case 'link' :
                                                                                printf(
                                                                                        '<div class="et_link_content%3$s"%4$s>
                                                                                                <a href="%1$s" class="et_link_main_url">%2$s</a>
                                                                                        </div> <!-- .et_link_content -->',
                                                                                        esc_url( et_get_link_url() ),
                                                                                        esc_html( et_get_link_url() ),
                                                                                        esc_attr( $text_color_class ),
                                                                                        et_core_esc_previously( $inline_style )
                                                                                );

                                                                                break;
                                                                }

                                                        endif;
                                                ?>
                                        </div> <!-- .et_post_meta_wrapper -->
                                <?php  } ?>

                                        <div class="entry-content">
                                        <?php
                                                do_action( 'et_before_content' );

                                                the_content();

                                                wp_link_pages( array( 'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'Divi' ), 'after' => '</div>' ) );
                                        ?>
                                        </div> <!-- .entry-content -->
                                        <div class="et_post_meta_wrapper">
                                        <?php
                                        if ( et_get_option('divi_468_enable') === 'on' ){
                                                echo '<div class="et-single-post-ad">';
                                                if ( et_get_option('divi_468_adsense') !== '' ) echo et_core_intentionally_unescaped( et_core_fix_unclosed_html_tags( et_get_option('divi_468_adsense') ), 'html' );
                                                else { ?>
                                                        <a href="<?php echo esc_url(et_get_option('divi_468_url')); ?>"><img src="<?php echo esc_attr(et_get_option('divi_468_image')); ?>" alt="468" class="foursixeight" /></a>
                                <?php         }
                                                echo '</div> <!-- .et-single-post-ad -->';
                                        }

                                        /**
                                         * Fires after the post content on single posts.
                                         *
                                         * @since 3.18.8
                                         */                                        do_action( 'et_after_post' );

                                                if ( ( comments_open() || get_comments_number() ) &amp;&amp; 'on' === et_get_option( 'divi_show_postcomments', 'on' ) ) {
                                                        comments_template( '', true );
                                                }
                                        ?>
                                        </div> <!-- .et_post_meta_wrapper -->
                                </article> <!-- .et_pb_post -->

                        <?php endwhile; ?>
                        </div> <!-- #left-area -->

                        <?php get_sidebar(); ?>
                </div> <!-- #content-area -->
        </div> <!-- .container -->
        <?php endif; ?>
</div> <!-- #main-content -->

<?php

get_footer();

Bon ça fait pas mal d’informations comme ça et il n’est pas forcément évident de s’y retrouver. Voici un petit descriptif des lignes mise en évidence dans le code :

  1. La récupération de l’en-tête et donc du menu, avec get_header()
  2. Une itération au travers de tous les posts avec while (have_posts()) qui affichera le contenu de votre article. Cette partie commence par définir l’en-tête de l’article en fonction de son type. Tout ça est spécifique à Divi.
  3. Le conteneur avec la classe entry-content qui s’occupera d’afficher le contenu de l’article. Il appel d’abord un filtre permettant d’afficher des informations avant le contenu, ensuite the_content() affiche le contenu de l’article et la méthode wp_link_pages() s’occupe d’afficher la pagination.
  4. Affichage de la fameuse barre latérale
  5. Et récupération du pied de page

Je vous propose une version commentée largement simplifiée, sans tous le décorum de Divi, pour vous aider à vous y retrouver :

<?php
    // En-tête - Menu, logo, etc.
    get_header(); 
?>

<div id="main-content">
    <div class="container">
        <div id="content-area" class="clearfix">
            <div id="left-area">
        
                <?php while ( have_posts() ) : the_post(); ?>
                    
                    <article id="post-<?php the_ID(); ?>" <?php post_class( 'et_pb_post' ); ?>>
                        
                        
                        <div class="et_post_meta_wrapper">
                            <!-- Titre -->                            
                            <h1 class="entry-title"><?php the_title(); ?></h1>

                            <?php

                                // Affichage des infos de l'article : date, auteur, catégorie, etc.
                                et_divi_post_meta();

                            ?>
                        </div>
                        
                        <?php 

                            // Contenu
                            the_content();

                            // Pagination
                            wp_link_pages( array( 'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'Divi' ), 'after' => '</div>' ) );

                        ?>
                        
                    </article>

                  <?php 

                      // Commentaires - Avec vérification s'ils doivent être affichés ou non
                      if ( ( comments_open() || get_comments_number() ) &amp;&amp; 'on' === et_get_option( 'divi_show_postcomments', 'on' ) ) {
                        comments_template( '', true );
                    }

                  ?>
                
                <?php endwhile; ?>
            
            </div><!-- #left-area -->

            <?php get_sidebar(); ?>
        </div><!-- #content-area -->
    </div><!-- .container -->
</div><!-- #main-content -->

<?php 
    // Pied de page
    get_footer();
?>

Cette conversion d’un fichier complexe vers un fichier simplifié vous permet de voir que vous avez le contrôle sur ce que vous affichez. Par exemple, vous n’utiliserez pas le constructeur Divi pour gérer cette page, alors pourquoi s’en soucier ?

Bien sûr vous pouvez vous inspiré du thème parent pour gérer les différents types d’articles (citations, vidéos, etc.) proposés par WordPress, mais pour un thème générique par défaut, ce deuxième fichier single.php suffit largement !

Vous remarquerez que les ID et classes des éléments HTML ont été conservés. Il n’est pas obligatoire de procéder de cette manière, certains styles peuvent vous encombrez, mais le mieux est de commencer avec les styles pré-définis du thème (adaptés au mobiles et qui fonctionnent bien par défaut) et de construire dessus.

Je ne vous guiderai pas pas à pas dans la modification de ce modèle, mais avec cette version simplifiée vous devriez pouvoir aisément créer ce dont vous avez besoins, les appels vers les méthodes PHP importantes sont toutes visibles ici, il ne reste plus qu’à écrire un peu de HTML et de CSS.

Et si vous avez des questions, n’hésitez pas à réagir dans les commentaires !

Astuces

Comme cet article n’est pas une démo complète de comment créer un modèle d’article, mais juste le point de départ, je vous propose de conclure avec 2 supers astuces pour aller encore plus loin avec les modèles de WordPress.

Utiliser un modèle spécifique en fonction de la catégorie

Cette option peut-être intéressant pour séparer différentes parties de votre blog ou de votre site. Je l’utilise moi-même pour gérer des modèles différents pour mes articles de ressources et mes articles de blog comme celui-ci.

Pour se faire, nous allons utiliser un filtre dans le fichier functions.php. Ce fichier doit se trouver à la racine de votre thème enfant.

Cette méthode s’exécutera sur le filtre appelé single_template, ce filtre est utilisé pour charger le modèle à utiliser en fonction de la requête donnée.

function my_single_template($single) {
    // Récupère la variable globale $post qui contient les informations de l'article demandé
    global $post;

    // Récupère le chemin vers les fichiers de style du thème, ce qui nous donne le chemin exact du dossier du thème enfant
    // auquel nous ajoutons le dossier "/single" dans lequel se trouveront nos modèles spécifiques à chaque catégorie
    $single_path = get_stylesheet_directory() . '/single';
 
    // Cette boucle traverse toutes les catégories de l'article actuel
    foreach((array)get_the_category() as $cat) :
            
            // Pour chaque catégorie le système va voir si un fichier existe pour cette catégorie
            // Par exemple si cet article appartient à la catégorie "SEO" dont le slug est "seo"
            // cette fonction regardera si le fichier "/single/single-seo.php" existe.
            // Si ce fichier existe c'est cette valeur qui est retournée et WordPress utilisera ce modèle
            if(file_exists($single_path . '/single-' . $cat->slug . '.php'))
            return $single_path . '/single-' . $cat->slug . '.php';
     
    endforeach;
}

// Enregistrement du filtre
add_filter('single_template', 'my_single_template');

Ce code commenté devrait être suffisamment clair. Tout ce qu’il vous reste à faire est de créer un dossier single dans votre thème enfant et d’y ajouter les modèles spécifiques aux catégories qui vous intéressent sous la forme :

single-[slug de la catégorie].php

Et le mieux, c’est que ce filtre laisse le comportement de base de WordPress en fonction. Donc si un article est de catégorie Webdesign avec le slug webdesign mais qu’aucun fichier appelé :

[thème enfant]/single/single-webdesign.php 

N’est trouvé, WordPress se rabattra sur le bon vieux :

[thème enfant]/single.php

Et s’il n’existe pas continuera son chemin jusqu’à index.php. Plutôt cool non ?

Utiliser le Divi Builder pour créer votre modèle

Petite astuce sympa si vous utilisez Divi, il est possible d’utiliser le Divi Builder pour construire des parties de votre modèle.

Je m’explique : si vous regardez mon site vous verrez qu’en bas de page s’affiche systématiquement le même pied de page. Ce pied de page a été créé dans Divi comme élément global et si je le modifie dans la librairie de Divi, il sera modifié sur toutes les pages.

Sympa non ? Du coup, dans mon fichier single.php, qui me permet d’afficher mes articles, j’aimerais pouvoir utiliser le même pied de page.

Je pourrais bien sûr m’amuser à copier coller le code HTML du pied de page, mais à chaque modification de ce dernier, je devrais refaire l’opération.

Avec cette astuce, réutilisez une section ou une ligne enregistrée dans Divi dans vos modèle personnalisé. Commencez par enregistrer l’élément qui vous intéresse dans votre bibliothèque Divi.

Enregistrer une section dans Divi

Pour information, il n’est pas nécessaire d’en faire un élément global pour que cette technique fonctionne même après modification de l’élément.

Enregistrer une section dans Divi

Une fois l’élément enregistré, dans votre console d’administration rendez-vous dans Divi > Bibliothèque Divi pour afficher tous les éléments enregistrés.

Enregistrer une section dans Divi

Et passez avec la souris sur l’élément que vous souhaitez afficher dans votre modèle. Comme précédemment, ceci vous affichera le lien vers l’élément et vous obtiendrez son ID unique présent dans l’attribut post :

Enregistrer une section dans Divi

Ensuite dans votre modèle, il suffit d’appeler le shortcode permettant de charger cet élément. Pour cet exemple, il faut utiliser le shortcode fourni par Divi permettant d’afficher une section.

On affichera donc le résultat (grâce à echo) de l’appel de la méthode do_shortcode qui exécutera le shortcode donné en paramètre. Ce shortcode contiendra le type d’élément à afficher et l’ID unique de cet élément :

<div>
    <?php echo do_shortcode('[et_pb_section global_module="154"]][/et_pb_section]'); ?>
</div>

Attention a bien choisir le shortcode spécifique au type d’élément enregistré dans la librairie.

  • Section : [et_pb_section]
  • Ligne : [et_pb_row]

Ensuite rien ne vous empêche d’aller modifier cet élément dans la librairie. Vous pourrez alors constater que cette modification se sera répercutée dans votre modèle personnalisé.

C’est pas beau ça ?


0 commentaires

Soumettre un commentaire

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

derniers articles
de mon blog

Le droit d’auteur des images sur Internet en 2019

« Sur Google Images, j’ai trouvé une superbe photo du Machu Picchu. Une fois la signature de l’auteur effacée avec Photoshop, ça aura une sacrée gueule sur la page d’accueil de mon blog de voyage! » Les droits d’auteur sur Internet vous connaissez? Bon, je vous conseil de lire ce qui suit.

Pin It on Pinterest