Développer son premier thème de blog WordPress

Développer son premier thème de blog WordPress

Catégories du post

Pour le bon déroulement de ce tuto, je vais prendre en considération que vous avez téléchargé WordPress et que vous l’avez déjà installé dans votre environnement PHP (XAMPP, WampServer, etc.). Vous avez donc une installation toute fraîche de WordPress et êtes prêt à coder.

Pour votre confort, vous devez également avoir un éditeur de texte (Notepad++, Sublime Text, etc.) qui supporte les tabulations avec espace si vous ne voulez pas vous rendre chèvre avec les copiés/collés de ce tuto. Enfin, pour éviter quelque frustration, je vous recommande de ne pas modifier le code que vous allez copier/coller avant la toute fin du tuto vu qu’on va revenir dessus pas mal de fois pour modifier/supprimer des lignes, etc.

Let’s go !

Création de l’arborescence du thème

Dans WordPress, le thème est un regroupement de dossiers et de fichiers permettant de surcharger le fonctionnement par défaut du CMS. Pour qu’un thème soit reconnu par WordPress, il va falloir au minimum 3 choses :

  • Un dossier contenant votre thème
  • Un fichier CSS avec l’entête approprié à la racine de ce dossier
  • Un fichier index.php placé à la racine de ce dossier également

Allez à l’emplacement /wp-content/themes/ et créez-y un dossier avec le nom que vous voulez. Pour cet exemple, on va utiliser le nom « montheme », de manière à se retrouver avec le chemin /wp-content/themes/montheme.

Dans ce dossier, créez un fichier style.css dans lequel vous taperez :

/*   
Theme Name: Mon Thème
Theme URI: Accueil du thème
Description: Une description du thème
Author: Prénom Nom
*/

Ces quelques lignes commentées en haut de cette feuille de style permettront à votre thème d’apparaître dans l’administration de WordPress. Vous pourrez ainsi le sélectionner et l’activer.

Créez ensuite un fichier index.php dans le dossier avec le code suivant :

<!doctype html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <title>Titre de la page</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    C'est mon thème !
</body>
</html>

Activation du thème dans l’administration

Rendez-vous maintenant dans votre administration WordPress et allez dans la rubrique Apparence.

Trouvez votre thème et activez-le en survolant sa miniature et en appuyant sur le bouton « Activer ».

Le thème est activé ! Retournez sur votre site et rafraichissez la page. Vous constaterez que le texte « C’est mon thème ! » apparaît tout en haut à gauche sur un grand fond blanc. Il va maintenant falloir mettre ça en page.

Mise en page avec Bootstrap

Pour des besoins de simplicité (et aussi parce que c’est cool), nous allons utiliser Bootstrap comme Framework CSS.

Avant toute chose, intéressons-nous aux différents exemples de mise en page par défaut que propose Bootstrap v5. Nous allons utiliser le modèle Blog. Vous pouvez, soit télécharger le modèle, soit aller sur l’exemple et faire ctrl+U depuis votre navigateur pour en analyser le code source. Quoiqu’il en soit, reprenez votre fichier index.php, supprimez tout ce qui s’y trouve et copiez/collez ce qui suit :

<!doctype html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Mon blog</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-uWxY/CJNBR+1zjPWmfnSnVxwRheevXITnMqoEIeG1LJrdI0GlVs/9cVSyPYXdcSF" crossorigin="anonymous">
    <link href="https://fonts.googleapis.com/css?family=Playfair&#43;Display:700,900&amp;display=swap" rel="stylesheet">
</head>
<body>  
    <div class="container">
        <header class="blog-header py-3">
            <div class="row flex-nowrap justify-content-between align-items-center">
                <div class="col-8 pt-1">
                    <span>LE LOGO DE MON BLOG</span>
                </div>
            </div>
        </header>
        <div class="nav-scroller py-1 mb-2">
            <nav class="nav d-flex justify-content-between">
                <a class="p-2 link-secondary" href="#">World</a>
                <a class="p-2 link-secondary" href="#">U.S.</a>
                <a class="p-2 link-secondary" href="#">Technology</a>
                <a class="p-2 link-secondary" href="#">Design</a>
                <a class="p-2 link-secondary" href="#">Culture</a>
                <a class="p-2 link-secondary" href="#">Business</a>
                <a class="p-2 link-secondary" href="#">Politics</a>
                <a class="p-2 link-secondary" href="#">Opinion</a>
                <a class="p-2 link-secondary" href="#">Science</a>
                <a class="p-2 link-secondary" href="#">Health</a>
                <a class="p-2 link-secondary" href="#">Style</a>
                <a class="p-2 link-secondary" href="#">Travel</a>
            </nav>
        </div>
    </div>
    <main class="container">
        <div class="p-4 p-md-5 mb-4 text-white rounded bg-dark">
            <div class="row">
                <div class="col-md-6">
                    <h1 class="display-4 fst-italic">Titre très long, vraiment très long, d'un très long post</h1>
                    <p class="lead my-3">Nunc iaculis cursus orci nec porta. Duis pretium efficitur lectus, eget placerat justo ultricies id. Mauris tempor neque a nunc suscipit</p>
                    <p class="lead mb-0"><a href="#" class="text-white fw-bold">En savoir plus</a></p>
                </div>
            </div>
        </div>
        <div class="row mb-2">
            <div class="col-md-6">
                <div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
                    <div class="col p-4 d-flex flex-column position-static">
                        <strong class="d-inline-block mb-2 text-primary">Catégorie 1</strong>
                        <h3 class="mb-0">Post mis en avant</h3>
                        <div class="mb-1 text-muted">12 Novembre</div>
                        <p class="card-text mb-auto">Donec id ornare felis, in convallis ligula. Sed in elit id mauris ultricies ullamcorper.</p>
                        <a href="#" class="stretched-link">En savoir plus</a>
                    </div>
                    <div class="col-auto d-none d-lg-block">
                        <img src="https://loremflickr.com/200/250" alt="">
                    </div>
                </div>
            </div>
            <div class="col-md-6">
                <div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
                    <div class="col p-4 d-flex flex-column position-static">
                        <strong class="d-inline-block mb-2 text-primary">Catégorie 2</strong>
                        <h3 class="mb-0">Deuxième post mis en avant</h3>
                        <div class="mb-1 text-muted">13 Novembre</div>
                        <p class="card-text mb-auto">Vivamus libero leo, fringilla at tellus non, rhoncus maximus tortor</p>
                        <a href="#" class="stretched-link">En savoir plus</a>
                    </div>
                    <div class="col-auto d-none d-lg-block">
                        <img src="https://loremflickr.com/200/250" alt="">
                    </div>
                </div>
            </div>
        </div>
        <div class="row g-5">
            <div class="col-md-8">
                <h3 class="pb-4 mb-4 fst-italic border-bottom">
                    Derniers articles
                </h3>
                <article class="blog-post">
                    <h2 class="blog-post-title">Extrait de post 1</h2>
                    <p class="blog-post-meta">01/01/2145 par Moi-même</p>
                    <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Aut ipsa reiciendis aspernatur quod itaque aliquid, similique explicabo nesciunt, eligendi sint nostrum totam libero iusto nulla vel quae, incidunt, repellendus numquam.</p>
                    <p>Facere adipisci distinctio sequi expedita neque vero magnam repellat quo quas est obcaecati, a porro veritatis aliquam, dignissimos veniam iure minima consequuntur nam, nemo beatae voluptates in error! Tenetur, voluptatum.</p>
                    <p>Magni quos at dolor dolores modi molestias consequuntur distinctio praesentium, nobis. Vero inventore accusantium dicta amet ipsa sapiente, soluta eligendi vel totam, sint, ullam, doloremque neque natus dolorum? Nulla, tenetur.</p>
                </article>
                <article class="blog-post">
                    <h2 class="blog-post-title">Extrait de post 2</h2>
                    <p class="blog-post-meta">12/10/2145 par Moi-même</p>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eos quam, reprehenderit itaque, aspernatur ducimus ipsam hic, veritatis, laborum iste sapiente optio accusantium numquam. Iure impedit animi facilis rem quibusdam id?</p>
                    <p>Quasi ducimus voluptatum quis quod modi eaque voluptatibus, sint dolore tempore obcaecati? Adipisci ea beatae in assumenda fugiat, dicta architecto sequi asperiores nam nulla dolorem dolor ab magni, illo, necessitatibus.</p>
                    <p>Sapiente nihil ab fuga consequuntur expedita soluta error, aliquam nostrum dicta, qui non laudantium, cumque itaque deleniti voluptates earum quidem natus rem ipsam dolor. Necessitatibus officiis eveniet maxime. Maxime, distinctio.</p>
                </article>
                <article class="blog-post">
                    <h2 class="blog-post-title">Extrait de post 2</h2>
                    <p class="blog-post-meta">14/08/2146 par Moi-même</p>
                    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ducimus ipsum, vel, delectus sed temporibus provident animi debitis deserunt perferendis, illo omnis porro itaque, nulla. Delectus fuga id facilis necessitatibus ducimus?</p>
                    <p>Quidem, dolore? A ab aut officiis non doloribus tempora, saepe, aspernatur, architecto minus fugit itaque ipsam sapiente obcaecati inventore, nostrum iste excepturi libero debitis. Accusamus tempore blanditiis temporibus labore cum?</p>
                </article>
                <nav class="blog-pagination" aria-label="Pagination">
                    <a class="btn btn-outline-primary" href="#">Précédent</a>
                    <a class="btn btn-outline-secondary disabled">Suivant</a>
                </nav>
            </div>
            <div class="col-md-4">
                <div class="position-sticky" style="top: 2rem;">
                    <div class="p-4 mb-3 bg-light rounded">
                        <h4 class="fst-italic">A propos</h4>
                        <p class="mb-0">Quisque lacus tortor, dignissim non feugiat nec, vestibulum sit amet dui. Fusce rhoncus ultrices egestas. Fusce auctor tellus sed ex fringilla</p>
                    </div>
                    <div class="p-4">
                        <h4 class="fst-italic">Archives</h4>
                        <ol class="list-unstyled mb-0">
                            <li><a href="#">Mars 2021</a></li>
                            <li><a href="#">Avril 2021</a></li>
                            <li><a href="#">Mai 2021</a></li>
                            <li><a href="#">Juin 2021</a></li>
                        </ol>
                    </div>
                    <div class="p-4">
                        <h4 class="fst-italic">Réseaux</h4>
                        <ol class="list-unstyled">
                            <li><a href="#">GitHub</a></li>
                            <li><a href="#">Twitter</a></li>
                            <li><a href="#">Facebook</a></li>
                        </ol>
                    </div>
                </div>
            </div>
        </div>
    </main>
    <footer class="blog-footer">
        <p>Blog template built for <a href="https://getbootstrap.com/">Bootstrap</a> by <a href="https://twitter.com/mdo">@mdo</a>.</p>
        <p><a href="#">Retour en haut</a></p>
    </footer>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-kQtW33rZJAHjgefvhyyzcGF3C5TFyBQBA13V1RKPf4uH+bwyzQxZ6CmMZHmNBEfJ" crossorigin="anonymous"></script>  
</body>
</html>

Si vous rafraîchissez la page d’accueil de votre blog, vous devriez vous retrouver avec quelque chose qui ressemble à ça :

Pas d’inquiétude si les images ne sont pas identiques, elles sont aléatoires. D’ailleurs, vous remarquerez que le footer et d’autres éléments ne semblent pas en place. Nous allons remédier à ça dès maintenant.

L’intérêt principal de WordPress c’est qu’il est relié à une base de données et qu’il va nous permettre de créer du contenu via son interface d’administration. Hors, actuellement le blog n’est pas dynamique et ne récupère pas ces données. Il va donc falloir, une nouvelle fois, modifier notre fichier index.php mais également créer une arborescence plus avancée sous notre dossier montheme pour répondre à ces besoins. On y codera ensuite les différentes boucles de récupération d’articles, de catégories, etc.

Arborescence avancée et système de templates

Nous allons d’abord créer les templates (aussi appelés modèles) par défaut pour le blog. Ces fichiers ne sortent pas de nulle part, ils viennent en partie d’une liste de modèles par défaut de WordPress qu’il est possible de surcharger dans chaque thème que l’on crée. Pour que le moteur comprenne qu’on souhaite avoir notre version personnalisée de ces templates, il suffit tout simplement de les créer à la racine de notre thème.

Allez à la racine du dossier monthème et créez-y les fichiers suivants :

  • footer.php
  • header.php
  • sidebar.php

L’un des intérêts d’avoir ces templates c’est qu’on peut les appeler avec des fonctions php de WordPress telles que get_footer() pour récupérer le template du footer, get_header() pour récupérer le header, etc. Utiliser ce genre de fonctions standards est une bonne pratique quand vous codez avec WordPress et vous permettra, par exemple, d’éviter d’avoir des conflits ou des problèmes d’affichage lorsque vous activez des plug-ins développés par des tiers.

Copiez/collez ces lignes de codes dans les fichiers suivants :

header.php

<!doctype html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Mon blog</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-uWxY/CJNBR+1zjPWmfnSnVxwRheevXITnMqoEIeG1LJrdI0GlVs/9cVSyPYXdcSF" crossorigin="anonymous">
    <link href="https://fonts.googleapis.com/css?family=Playfair&#43;Display:700,900&amp;display=swap" rel="stylesheet">
</head>
<body>  
    <div class="container">
        <header class="blog-header py-3">
            <div class="row flex-nowrap justify-content-between align-items-center">
                <div class="col-8 pt-1">
                    <span>LE LOGO DE MON BLOG</span>
                </div>
            </div>
        </header>
        <div class="nav-scroller py-1 mb-2">
            <nav class="nav d-flex justify-content-between">
                <a class="p-2 link-secondary" href="#">World</a>
                <a class="p-2 link-secondary" href="#">U.S.</a>
                <a class="p-2 link-secondary" href="#">Technology</a>
                <a class="p-2 link-secondary" href="#">Design</a>
                <a class="p-2 link-secondary" href="#">Culture</a>
                <a class="p-2 link-secondary" href="#">Business</a>
                <a class="p-2 link-secondary" href="#">Politics</a>
                <a class="p-2 link-secondary" href="#">Opinion</a>
                <a class="p-2 link-secondary" href="#">Science</a>
                <a class="p-2 link-secondary" href="#">Health</a>
                <a class="p-2 link-secondary" href="#">Style</a>
                <a class="p-2 link-secondary" href="#">Travel</a>
            </nav>
        </div>
    </div>

sidebar.php

<div class="col-md-4">
    <div class="position-sticky" style="top: 2rem;">
        <div class="p-4 mb-3 bg-light rounded">
            <h4 class="fst-italic">A propos</h4>
            <p class="mb-0">Quisque lacus tortor, dignissim non feugiat nec, vestibulum sit amet dui. Fusce rhoncus ultrices egestas. Fusce auctor tellus sed ex fringilla</p>
        </div>
        <div class="p-4">
            <h4 class="fst-italic">Archives</h4>
            <ol class="list-unstyled mb-0">
                <li><a href="#">Mars 2021</a></li>
                <li><a href="#">Avril 2021</a></li>
                <li><a href="#">Mai 2021</a></li>
                <li><a href="#">Juin 2021</a></li>
            </ol>
        </div>
        <div class="p-4">
            <h4 class="fst-italic">Réseaux</h4>
            <ol class="list-unstyled">
                <li><a href="#">GitHub</a></li>
                <li><a href="#">Twitter</a></li>
                <li><a href="#">Facebook</a></li>
            </ol>
        </div>
    </div>
</div>

footer.php

    <footer class="blog-footer">
        <p>Blog template built for <a href="https://getbootstrap.com/">Bootstrap</a> by <a href="https://twitter.com/mdo">@mdo</a>.</p>
        <p><a href="#">Retour en haut</a></p>
    </footer>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-kQtW33rZJAHjgefvhyyzcGF3C5TFyBQBA13V1RKPf4uH+bwyzQxZ6CmMZHmNBEfJ" crossorigin="anonymous"></script>  
</body>
</html>

Et dans index.php, remplacez le code que vous aviez par celui-ci :

<?php get_header(); ?>
<main class="container">
    <div class="p-4 p-md-5 mb-4 text-white rounded bg-dark">
        <div class="row">
            <div class="col-md-6">
                <h1 class="display-4 fst-italic">Titre très long, vraiment très long, d'un très long post</h1>
                <p class="lead my-3">Nunc iaculis cursus orci nec porta. Duis pretium efficitur lectus, eget placerat justo ultricies id. Mauris tempor neque a nunc suscipit</p>
                <p class="lead mb-0"><a href="#" class="text-white fw-bold">En savoir plus</a></p>
            </div>
        </div>
    </div>
    <div class="row mb-2">
        <div class="col-md-6">
            <div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
                <div class="col p-4 d-flex flex-column position-static">
                    <strong class="d-inline-block mb-2 text-primary">Catégorie 1</strong>
                    <h3 class="mb-0">Post mis en avant</h3>
                    <div class="mb-1 text-muted">12 Novembre</div>
                    <p class="card-text mb-auto">Donec id ornare felis, in convallis ligula. Sed in elit id mauris ultricies ullamcorper.</p>
                    <a href="#" class="stretched-link">En savoir plus</a>
                </div>
                <div class="col-auto d-none d-lg-block">
                    <img src="https://loremflickr.com/200/250" alt="">
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
                <div class="col p-4 d-flex flex-column position-static">
                    <strong class="d-inline-block mb-2 text-primary">Catégorie 2</strong>
                    <h3 class="mb-0">Deuxième post mis en avant</h3>
                    <div class="mb-1 text-muted">13 Novembre</div>
                    <p class="card-text mb-auto">Vivamus libero leo, fringilla at tellus non, rhoncus maximus tortor</p>
                    <a href="#" class="stretched-link">En savoir plus</a>
                </div>
                <div class="col-auto d-none d-lg-block">
                    <img src="https://loremflickr.com/200/250" alt="">
                </div>
            </div>
        </div>
    </div>
    <div class="row g-5">
        <div class="col-md-8">
            <h3 class="pb-4 mb-4 fst-italic border-bottom">
                Derniers articles
            </h3>
            <article class="blog-post">
                <h2 class="blog-post-title">Extrait de post 1</h2>
                <p class="blog-post-meta">01/01/2145 par Moi-même</p>
                <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Aut ipsa reiciendis aspernatur quod itaque aliquid, similique explicabo nesciunt, eligendi sint nostrum totam libero iusto nulla vel quae, incidunt, repellendus numquam.</p>
                <p>Facere adipisci distinctio sequi expedita neque vero magnam repellat quo quas est obcaecati, a porro veritatis aliquam, dignissimos veniam iure minima consequuntur nam, nemo beatae voluptates in error! Tenetur, voluptatum.</p>
                <p>Magni quos at dolor dolores modi molestias consequuntur distinctio praesentium, nobis. Vero inventore accusantium dicta amet ipsa sapiente, soluta eligendi vel totam, sint, ullam, doloremque neque natus dolorum? Nulla, tenetur.</p>
            </article>
            <article class="blog-post">
                <h2 class="blog-post-title">Extrait de post 2</h2>
                <p class="blog-post-meta">12/10/2145 par Moi-même</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eos quam, reprehenderit itaque, aspernatur ducimus ipsam hic, veritatis, laborum iste sapiente optio accusantium numquam. Iure impedit animi facilis rem quibusdam id?</p>
                <p>Quasi ducimus voluptatum quis quod modi eaque voluptatibus, sint dolore tempore obcaecati? Adipisci ea beatae in assumenda fugiat, dicta architecto sequi asperiores nam nulla dolorem dolor ab magni, illo, necessitatibus.</p>
                <p>Sapiente nihil ab fuga consequuntur expedita soluta error, aliquam nostrum dicta, qui non laudantium, cumque itaque deleniti voluptates earum quidem natus rem ipsam dolor. Necessitatibus officiis eveniet maxime. Maxime, distinctio.</p>
            </article>
            <article class="blog-post">
                <h2 class="blog-post-title">Extrait de post 3</h2>
                <p class="blog-post-meta">14/08/2146 par Moi-même</p>
                <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ducimus ipsum, vel, delectus sed temporibus provident animi debitis deserunt perferendis, illo omnis porro itaque, nulla. Delectus fuga id facilis necessitatibus ducimus?</p>
                <p>Quidem, dolore? A ab aut officiis non doloribus tempora, saepe, aspernatur, architecto minus fugit itaque ipsam sapiente obcaecati inventore, nostrum iste excepturi libero debitis. Accusamus tempore blanditiis temporibus labore cum?</p>
            </article>
            <nav class="blog-pagination" aria-label="Pagination">
                <a class="btn btn-outline-primary" href="#">Précédent</a>
                <a class="btn btn-outline-secondary disabled">Suivant</a>
            </nav>
        </div>
        <?php get_sidebar(); ?>
    </div>
</main>
<?php get_footer(); ?>

Le code est maintenant « explosé » dans de multiples fichiers, allégeant ainsi index.php sur lequel on reviendra un peu plus tard. Pour le moment, dans un souci de standardisation, nous allons ajouter de nouveaux éléments à notre arborescence. L’un des problèmes de notre code actuel est que si un plug-in a besoin d’ajouter des éléments graphiques via du CSS ou autres interactions via du javascript, il n’y a aucun endroit dans notre code qui lui permet de le faire. Nous allons remédier à ça, et nous allons en profiter pour voir comment ajouter nos feuilles de style et du javascript via le fichier functions.php de WordPress.

A la racine de montheme créez un fichier functions.php, puis, toujours à la racine, créez un dossier css dans lequel vous ajouterez un fichier blog.css.

Vous devriez maintenant avoir l’arborescence suivante :

  • css
    • blog.css
  • footer.php
  • functions.php
  • header.php
  • index.php
  • sidebar.php
  • style.css

Tout d’abord, copiez-collez ceci dans css/blog.css. Il s’agit de la feuille style de l’exemple Bootstrap.

.blog-header {
    line-height: 1;
    border-bottom: 1px solid #e5e5e5;
}

.blog-header-logo {
    font-family: "Playfair Display", Georgia, "Times New Roman", serif/*rtl:Amiri, Georgia, "Times New Roman", serif*/;
    font-size: 2.25rem;
}

.blog-header-logo:hover {
    text-decoration: none;
}

h1, h2, h3, h4, h5, h6 {
    font-family: "Playfair Display", Georgia, "Times New Roman", serif/*rtl:Amiri, Georgia, "Times New Roman", serif*/;
}

.display-4 {
    font-size: 2.5rem;
}
@media (min-width: 768px) {
    .display-4 {
        font-size: 3rem;
    }
}

.nav-scroller {
    position: relative;
    z-index: 2;
    height: 2.75rem;
    overflow-y: hidden;
}

.nav-scroller .nav {
    display: flex;
    flex-wrap: nowrap;
    padding-bottom: 1rem;
    margin-top: -1px;
    overflow-x: auto;
    text-align: center;
    white-space: nowrap;
    -webkit-overflow-scrolling: touch;
}

.nav-scroller .nav-link {
    padding-top: .75rem;
    padding-bottom: .75rem;
    font-size: .875rem;
}

.card-img-right {
    height: 100%;
    border-radius: 0 3px 3px 0;
}

.flex-auto {
    flex: 0 0 auto;
}

.h-250 { 
    height: 250px; 
}

@media (min-width: 768px) {
    .h-md-250 { 
        height: 250px; 
    }
}

/* Pagination */
.blog-pagination {
    margin-bottom: 4rem;
}
.blog-pagination > .btn {
    border-radius: 2rem;
}

/*
* Blog posts
*/
.blog-post {
    margin-bottom: 4rem;
}
.blog-post-title {
    margin-bottom: .25rem;
    font-size: 2.5rem;
}
.blog-post-meta {
    margin-bottom: 1.25rem;
    color: #727272;
}

/*
* Footer
*/
.blog-footer {
    padding: 2.5rem 0;
    color: #727272;
    text-align: center;
    background-color: #f9f9f9;
    border-top: .05rem solid #e5e5e5;
}
.blog-footer p:last-child {
    margin-bottom: 0;
}

Ensuite, copiez/collez ceci dans functions.php :

<?php

function theme_enqueue_scripts() {
	wp_enqueue_style('bootstrap-css', 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css', array(), true);
	wp_enqueue_style('google-font-playfair', 'https://fonts.googleapis.com/css?family=Playfair+Display:700,900&display=swap', false);
    wp_enqueue_style('main-css', get_template_directory_uri().'/css/blog.css', array(), true);
    wp_enqueue_script('bootstrap-js', 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js', array(), true, true);
}
add_action('wp_enqueue_scripts', 'theme_enqueue_scripts');

?>

On va utiliser la fonction wp_enqueue_style() pour ajouter les unes à la suite des autres les feuilles de style que l’on souhaite utiliser sur notre blog. On va faire pareil avec wp_enqueue_script() pour le javascript. Puis on va indiquer à une fonction de hook – add_action() – d’ajouter tout ça dans une pile virtuelle. WordPress utilisera alors tous les fichiers CSS et les fichiers javascript qui sont dans cette pile, qu’ils viennent de l’installation de base, d’un plugin que vous aurez installé ou directement de vous. On notera que le 5ème paramètre de wp_enqueue_script() nous permet d’indiquer que l’on souhaite que ce fichier javascript soit chargé dans le footer.

Pour indiquer au blog qu’il doit récupérer les fichiers qui ont été mis dans cette pile, nous allons modifier le header et le footer.

Dans header.php, remplacez le contenu des balises <head></head> par ceci :

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Mon blog</title>
    <?php wp_head(); ?>
</head>

Dans footer.php, remplacez tout le code par ceci :

    <footer class="blog-footer">
        <p>Blog template built for <a href="https://getbootstrap.com/">Bootstrap</a> by <a href="https://twitter.com/mdo">@mdo</a>.</p>
        <p><a href="#">Retour en haut</a></p>
    </footer>
    <?php wp_footer(); ?>
</body>
</html>

Quand vous rafraîchissez votre page d’accueil, vous devriez obtenir quelque chose comme ceci :

On a confirmation que la feuille de style blog.css et que la police d’écriture de Google qu’on a ajouté dans la queue de functions.php sont bien prises en compte. Passons maintenant au code PHP.

Code PHP : Mise en place du menu principal, de la barre latérale et autres détails de l’interface

Pour que votre thème supporte l’affichage du menu dynamique de WordPress, il va falloir l’activer.

Allez dans functions.php et ajoutez les lignes suivantes à la suite de votre code :

register_nav_menus(array(
	'main-menu' => 'Menu principal'
));

De manière à obtenir ceci :

<?php

function theme_enqueue_scripts() {
	wp_enqueue_style('bootstrap-css', 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css', array(), true);
	wp_enqueue_style('google-font-playfair', 'https://fonts.googleapis.com/css?family=Playfair+Display:700,900&display=swap', false);
    wp_enqueue_style('main-css', get_template_directory_uri().'/css/blog.css', array(), true);
    wp_enqueue_script('bootstrap-js', 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js', array(), true, true);
}
add_action('wp_enqueue_scripts', 'theme_enqueue_scripts');

register_nav_menus(array(
	'main-menu' => 'Menu principal'
));

?>

Maintenant, rendez-vous dans l’administration de WordPress. Vous constaterez que sous le menu Apparence se trouve maintenant la rubrique Menu. Cliquez dessus.

C’est ici que vous pourrez organiser les différentes pages, rubriques, etc. qui seront affichées dans les différents menus de votre blog. Pour le moment, nous allons nous occuper du menu principal. Ecrivez « Menu principal » dans le champ Nom du menu, puis cliquez sur Créer le menu. Cochez la case Afficher l’emplacement -> Menu principal, puis cliquez sur Enregistrer le menu.

Allez dans header.php, et remplacez le contenu du fichier par ceci :

<!doctype html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Mon blog</title>
    <?php wp_head(); ?>
</head>
<body>  
    <div class="container">
        <header class="blog-header py-3">
            <div class="row flex-nowrap justify-content-between align-items-center">
                <div class="col-8 pt-1">
                    <span>LE LOGO DE MON BLOG</span>
                </div>
            </div>
        </header>
        <div class="nav-scroller py-1 mb-2">
            <?php
                $mainMenu = wp_get_nav_menu_items('Menu principal');
                if($mainMenu):
            ?>
            <nav class="nav d-flex justify-content-between">
                <?php foreach($mainMenu as $elem): ?>
                    <a class="p-2 link-secondary" href="<?php echo $elem->url; ?>"><?php echo $elem->title; ?></a>
                <?php endforeach; ?>
            </nav>
            <?php
                endif;
            ?>
        </div>
    </div>

Quand vous rafraîchissez votre page, vous devriez avoir un résultat de ce genre :

Les éléments du menu sont très espacés – c’est le CSS de ce modèle de blog qui veut ça – mais ils sont bien là.

Maintenant on va afficher dynamiquement le nom du blog et en profiter pour réparer une bêtise que j’avais faite en nettoyant le code HTML (j’avais inversé le logo et un autre élément du header).

Dans header.php, trouvez la balise <header> et remplacez-la par celle-ci :

<header class="blog-header py-3">
    <div class="row flex-nowrap justify-content-between align-items-center">
        <div class="col-12 text-center">
            <a class="blog-header-logo text-dark" href="#"><?php echo get_bloginfo('name'); ?></a>
        </div>
    </div>
</header>

Toujours dans le fichier header.php, trouvez la balise <title> qui se situe elle-même, tout en haut, dans la balise <head> et remplacez-la par ceci :

<title>
    <?php if(is_front_page() || is_home()) {
        echo get_bloginfo('name');
    } else {
        echo wp_title('');
    } ?>
</title>

Cela aura pour effet de donner à la meta title :
1. le nom du site quand on se trouve sur la page d’accueil,
2. le titre du contenu affiché quand on se trouve n’importe où ailleurs sur le blog.

Pour la barre latérale, nous allons organiser les choses autrement. Nous allons isoler les différents blocs qui forment cette colonne et en faire des templates séparés. Rien d’obligatoire ici, il s’agit simplement d’avoir un aspect un peu plus « modulaire » pour notre thème. On pourra ainsi appeler les blocs comme on le souhaite par la suite en mélangeant très peu le php et le html. Ca fera plus propre et ça sera plus clair.

A la racine de montheme, créez un dossier appelé « parts », puis créez :

  • parts/bloc-a_propos.php
  • parts/bloc-archives.php
  • parts/bloc-reseaux_sociaux.php

Attention à bien respecter les différents tirets « – » et « _ ». Ils ont leur importance.

Dans sidebar.php, remplacez tout le code par ceci :

<div class="col-md-4">
    <div class="position-sticky" style="top: 2rem;">
        <?php 
            if (is_home()) get_template_part('parts/bloc', 'a_propos'); 
            get_template_part('parts/bloc', 'archives');
            get_template_part('parts/bloc', 'reseaux_sociaux');
        ?>
    </div>
</div>

Ensuite, dans bloc-a_propos.php :

<?php 
    $description = '';
    $description = get_the_author_meta('description', 1);
if($description != ''): 
?> 
<div class="p-4 mb-3 bg-light rounded">
    <h4 class="fst-italic">A propos</h4>
    <p class="mb-0"><?php echo $description; ?></p>
</div>
<?php endif; ?>

Ici, on va se servir de la description de l’auteur principal du blog. Au niveau de l’administration, cette description se trouve dans Comptes>Admin>Renseignements biographiques. Si ce champ est vide, le bloc A propos ne s’affichera pas.

Dans bloc-archives.php :

<div class="p-4">
    <h4 class="fst-italic">Archives</h4>
    <ol class="list-unstyled mb-0">
        <?php wp_get_archives(['type' => 'monthly']); ?>
    </ol>
</div>

Pour le bloc des réseaux sociaux, nous allons nous rendre dans l’administration de WordPress au même endroit où nous avons créé le menu principal. En haut de cette page d’administration, cliquez sur le lien « créer un nouveau menu ». En nom de menu, écrivez « Réseaux sociaux », puis ajoutez les éléments de menu de type « lien personnalisé » afin d’obtenir quelque chose comme ceci :

Dans bloc-reseaux_sociaux.php, copiez/collez ceci :

<div class="p-4">
    <h4 class="fst-italic">Réseaux</h4>
    <?php
        $socialMenu = wp_get_nav_menu_items('Réseaux sociaux');
        if($socialMenu):
    ?>
        <ol class="list-unstyled">
            <?php foreach($socialMenu as $elem): ?>
                <li><a href="<?php echo $elem->url; ?>" target="_blank"><?php echo $elem->title; ?></a></li>
            <?php endforeach; ?>
        </ol>
    <?php
        endif;
    ?>
</div>

Votre barre latérale devrait ressembler à ça :

Voilà, maintenant nous avons nos menus principaux, latéraux, etc. mais aucun lien interne ne marche. C’est tout simplement dû au fait que le fichier index.php ne traite aucune donnée pour le moment. Pour comprendre comment marche le blog, il faut imaginer que le fichier index.php est un carrefour avec de multiples sorties et que ces sorties ne sont accessibles que sous certaines conditions : est-ce que je veux afficher la page d’accueil ? est-ce que je veux afficher une liste d’article ? est-ce que je veux afficher un seul article en particulier ? etc. Pour répondre à ces conditions, il va nous falloir encore du code PHP et c’est ce que nous allons voir dans cette dernière partie.

Code PHP : Appeler les différentes pages du blog

Tout d’abord, insérez cette ligne dans functions.php :

add_theme_support('post-thumbnails');

Cette ligne nous permet d’activer l’insertion d’images miniatures pour nos articles.

Dans l’administration de WordPress, créez rapidement 4 ou 5 articles (Articles > Ajouter) à l’aide d’un outil comme Lorem Ipsum. Vous pourrez les supprimer plus tard, mais pour le moment ça nous aidera dans notre mise en page.

Ci-dessus, on peut voir que j’ai créé un article avec du texte généré aléatoirement. Je me suis également servi d’images aléatoires trouvées sur Loremflickr, j’en ai inséré une dans le contenu et une dans le bloc à droite appelé « Image mise en avant ». Enfin, dans le bloc « Extrait » de la colonne de droite, j’ai écrit un petit texte descriptif.

A la racine de montheme, créez un dossier appelé columns et un dossier appelé content. Puis dans ces dossiers, créez :

  • columns/homepage.php
  • columns/standard.php
  • content/post-full.php
  • content/post-excerpt.php
  • content/list-full.php

L’arborescence finale pour ce tuto doit ressembler à ça :

Dans index.php, remplacez votre code par ceci :

<?php get_header(); ?>
<main class="container">
    <?php
    if (have_posts()) : 
        if(is_home()) :
            get_template_part('columns/homepage', get_post_format(), array('display' => 'home'));
        elseif(is_archive()):
            get_template_part('columns/standard', get_post_format(), array('display' => 'posts_list'));
        else :
            while (have_posts()) :
                get_template_part('columns/standard', get_post_format(), array('display' => 'post_full'));
            endwhile;
        endif;
    else :  
        get_template_part('columns/standard');
    endif;
    ?>
</main>
<?php get_footer(); ?>

Dans columns/homepage.php :

<?php
    $maxStickyPosts = 3;
    /* pour les posts mis en avant sur la page d'accueil, on ne récupère que les posts 'sticky' */
    $sticky = get_option('sticky_posts');
    $args = array('post__in' => $sticky );
    query_posts($args);

    $postsList = array();
    if(have_posts()) {
        while(have_posts()) {
            the_post();
            array_push($postsList, get_the_ID());
        }
    }
?>

<?php
    if(count($postsList) > 0):
        get_post($postsList[0]);
        the_post();
?>  
    <div class="p-4 p-md-5 mb-4 text-white rounded bg-dark">
        <div class="row">
            <div class="col-md-6">
                <h1 class="display-4 fst-italic"><?php the_title(); ?></h1>
                <p class="lead my-3"><?php the_excerpt(); ?></p>
                <p class="lead mb-0"><a href="<?php echo get_post_permalink(get_the_ID()); ?>" class="text-white fw-bold">En savoir plus</a></p>
            </div>
        </div>
    </div>
<?php 
    endif; 
?>

<?php 
    if(count($postsList) > 1): 
?>
        <div class="row mb-2">
        <?php
            $imgPath = '';
            foreach($postsList as $key => $postID):
                if($key > 0 && $key < $maxStickyPosts): 
                    get_post($postID);
                    the_post();
                    $imgPath = ''; 
                    if(get_the_post_thumbnail_url($postID) != false) :
                        $imgPath = get_the_post_thumbnail_url($postID);
                    endif;
        ?>
                    <div class="col-md-6">
                        <div class="row g-0 border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative">
                            <div class="col p-4 d-flex flex-column position-static">
                                <strong class="d-inline-block mb-2 text-primary"><?php the_category(' '); ?></strong>
                                <h3 class="mb-0"><?php the_title(); ?></h3>
                                <div class="mb-1 text-muted"><?php the_date(); ?></div>
                                <p class="card-text mb-auto"><?php the_excerpt(); ?></p>
                                <a href="<?php echo get_post_permalink(get_the_ID()); ?>" class="stretched-link">En savoir plus</a>
                            </div>
                            <?php if($imgPath != ''): ?>
                                <div class="col-auto d-none d-lg-block">
                                    <img src="<?php echo $imgPath; ?>" alt="<?php the_title(); ?>" />
                                </div>
                            <?php endif; ?>
                        </div>
                    </div>
        <?php 
                endif; 
            endforeach;
        ?>
        </div><!-- row -->
<?php
    endif;
?>

<div class="row g-5">
    <?php
        /* puis pour la liste, on ne récupère pas les posts déjà mis en avant au dessus */
        $sticky = get_option('sticky_posts');
        $args = array('post__not_in' => $sticky);
        query_posts($args);
        get_template_part('columns/standard', get_post_format(), array('display' => 'posts_list')); 
    ?>
    <?php get_sidebar(); ?>
</div>

Dans columns/standard.php :

<div class="row g-5">
    <?php 
        switch($args['display']):
            case 'posts_list':
                get_template_part('content/list', 'full');
                break;
            case 'post_full':
                if(have_posts()) the_post();
                get_template_part('content/post', 'full');
                break;
            default:
                get_template_part('content/list', 'full');
                break;
        endswitch;
    ?>
    <?php get_sidebar(); ?>
</div>

Dans content/list-full.php :

<div class="col-md-8">
    <?php if(is_home()) : ?>
        <h3 class="pb-4 mb-4 fst-italic border-bottom">Derniers articles</h3>
    <?php 
        else : 
            the_archive_title('<h3>', '</h3>'); 
        endif;
    ?>
    <?php
        while (have_posts()) : 
            the_post();
            get_template_part('content/post', 'excerpt');
        endwhile;
    ?>
    <?php the_posts_pagination(array('class' => 'btn btn-outline-primary')); ?>
</div>

Dans content/post-excerpt.php :

<article class="blog-post">
    <h3 class="blog-post-title"><?php the_title(); ?></h3>
    <p class="blog-post-meta"><?php the_date(); ?> par <?php the_author(); ?></p>
    <?php the_excerpt(); ?>
    <a href="<?php echo get_post_permalink(get_the_ID()); ?>">En savoir plus</a>
</article>

Dans content/post-full.php :

<div class="col-md-8">
    <article class="blog-post">
        <h2 class="blog-post-title"><?php the_title(); ?></h2>
        <p class="blog-post-meta"><?php the_date(); ?> par <?php the_author(); ?></p>
        <?php the_content(); ?>
    </article>
</div>

Et voilà ! Vous devriez maintenant obtenir ceci :

Et si vous cliquez sur un article, vous devriez avoir un équivalent de ceci qui s’affiche :

Voilà donc les bases pour la création d’un blog. Si vous préférez passer au développement d’un site : la première étape, après avoir créé une base comme celle de ce blog, pourrait être de créer vos propres pages personnalisées comme expliqué sur cette page.

S’abonner
Notifier de
guest

2 Commentaires
Inline Feedbacks
Voir tous les commentaires
Fred

Salutation, j’avais envie de faire ce taf, je l’ai pas encore fait, juste debuté en fait…. Mais tu me mâches bien le travail. Ca fera une excellente base pour aller plus loin avec ce thème !
Merci a toi 😉
Je note que juste que l’intégration d’un menu natif des exemples (avec sous menu) devrait etre la même galère a dev que pour la V4.
Tu m’autorise a partager ? Je fais ma refonte la …