Créer un blog statique avec Jekyll

Ou comment générer dynamiquement des pages web sans base de donnée

Posté par GraineDigitale le 3 mars 2017

Jekyll : Les nouvelles pratiques

Quel Joie ce fut de découvrir le générateur de site Jekyll ! Il y a des jours comme ça ou l’on se rend compte à quel point l’inertie des veilles routines oriente nos pratiques.

Après avoir créé de multiples sites web, du type blog ou galerie photos, je me disais que Wordpress s’imposer comme le choix numéro 1. C’était alors sans compter sur Jekyll qui est venu bousculer mes pratiques. Nombreux sont les articles qui tarient déloges ce nouveau concept de sites statiques et à la fois dynamqiue qui permet de s’extraire de monde PHP/MYSQL, j’inviterai donc le lecteur à se rendre compte lui même des avantages en se baladant sur google, j’en citerai tout de meme quelques-uns :

  • Pouvoir deployer un site web en quelques secondes
  • Oublier les bases de données
  • Profiter de la syntaxe Markdown pour la rédaction des articles
  • Automatiser la création des menus et catégories avec Liquid
  • Hébergement de sites gratuit avec GithubPages ou Netlify

Remarquons que Jekyll n’est qu’une entrée dans le monde de la génération de site statiques car il existe plusieurs alternatives comme Hugo ou Hexo .

Dans le cadre de cette article, nous verrons comment créer un site rapidement un site avec Jekyll. Nous utilserons Bootstrap 4 pour la mise en page CSS et nous déploierons enfin le site sur la plateforme [Netlify]’(https://www.netlify.com/){:target=”_blanck”}. Notre environement de travail étant sur Fedora , la partie concernant l’installation, est très certainement différente pour les autres OS comme Windows ou Mac.

Installation

Nous allons installer Jekyll à l’aide de Ruby :

sudo dnf install ruby-devel
gem install jekyll rubygem-bundler

Création d’un nouveau site jekyll

jekyll new mon-site

Déploiement du site en local

cd mon-site
bundle exec jekyll serve

La commande bundle exec va prendre en compte toutes les gems présentes dans le .Gemfile tandis que Jekyll serve appel le démarrage du serveur local du site à l’adresse : http://127.0.0.1:4000/

Déployer un blog statique sur netlify

Rien de mieux qu’un exemple pour apprendre à se servir de Jekyll. Notre site d’exemple Jekyll sera un site de Voyages avec un blog et une gallerie d’images. La structure du site sera la suivante :

- Accueil
- Voyages
  - Paris
  - Rome
  - Lisbonne
  - Londres
- Blog
- Contact

Mise en place de l’atelier de développement

Configurer votre gestionnaire de dépots GIT

Pour une meilleure gestion des sources , et un déploiement sur Netlify il est necessaire que le site Jekyll soit créé à la racine d’un dépot GIT. Un solution possible est de créer un dépot vide ( avec ReadMe ) directement depuis votre gestionnaire de sources préféré ( Bitbucket, Github…) et de le cloner sur votre ordinateur, il suffira ensuite de déplacer le contenu du Projet Jekyll dans ce répertoire.

git clone https://monCompteBitbucket@bitbucket.org/monNom/citytravels.git
cd citytravels
jekyll new citytravels
cd citytravels
mv * ../
cd ..
rm -r citytravels

Déployer le site de développement sur Netlify.

Avec la commande bundle exec jekyll serve, il est possible de lancer le site en local comme indiquer précédemment. Avec Netlify, il va etre possible de publier le site en ligne en utilisant votre compte bitbucket ou Github . Une fois votre dépot connecté, Netlify s’occupe la compilation et du déploiement . Voir les étapes en détails ici : Jekyll (3.0) on Netlify

Il suffit de mettre à jour votre dépot :

git add .
git commit -am "Lancement du site"
git push

Et Netlify servira votre site à une url automatique, qu’il est possible de personnaliser, dans mon cas, le site est visible à l’adresse : https://citytravels.netlify.com/

L’atelier étant pret, nous pouvons maintenant nous lancer dans le developpement du site qui n’est actuellement le blog vierge “ minima” par défaut de Jekyll.

Personnalisation du site Jekyll

La configuration par défaut

  • Dans Le fichier _config.yml se trouve les principales lignes de configuration necessaires à la compilation du site. On peut y modifier, le nom du site, de l’auteur, les repertoires cibles, les plugins à utiliser…

  • Dans le dossier _post seront rangés les articles du sites . Au format Markdown, les articles seront ajoutés généré automtiquement en html par Jekyll.

  • Chaque fichier .md à la racine du site sera considéré comme une page du site.

Mettre en place les feuilles de styles de Bootstrap 4

Préalables

Installation de Bootstrap dans le site Jekyll

Le framework boostrap rassemble une serie d’outils CSS et JS devenus incontournable à la tenue d’un site responsive respectant les bonnes pratiques. Jekyll n’est configuré pour acceuillir nativement les feuilles de styles CSS, il va falloir en premier lieu effectuer quelques manipulations :

Nous allons installer la derniere version de bootstrap 4 à l’aide du gestionnaire de librairie yarn, il va falloir l’installer sur notre OS Fedora (voir) :

curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash -
sudo dnf install yarn

A la racine du site , on entre :


$ yarn install
yarn install v1.5.1
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
info Lockfile not saved, no dependencies.
Done in 0.11s.

Puis on installe la dernière version de Bootstrap , dans la cas présent la v4.0.0 :

$ yarn add bootstrap@4.0.0
yarn add v1.5.1
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
warning " > bootstrap@4.0.0" has unmet peer dependency "jquery@1.9.1 - 3".
warning " > bootstrap@4.0.0" has unmet peer dependency "popper.js@^1.12.9".
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ bootstrap@4.0.0
info All dependencies
└─ bootstrap@4.0.0
Done in 0.53s.

Les deux warnings dans le code ci-desus nous informe qui va falloir aussi installer jquery@1.9.1 - 3 et popper.js@^1.12.9, ainsi :

$ yarn add jquery@>=3.0.0
warning package.json: No license field                                                                                                                       
warning No license field                                                                                                                                     
warning " > bootstrap@4.0.0" has unmet peer dependency "popper.js@^1.12.9".                                                                                  
warning No license field    

$ yarn add popper.js@^1.12.9
yarn add v1.5.1
warning package.json: No license field
warning No license field
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ popper.js@1.14.1
info All dependencies
└─ popper.js@1.14.1
warning No license field
Done in 0.46s.

Nous constatons enfin qu’un nouveau dossier node_modules est apparu à la racine du site, il contient toutes les librairies necessaires au bon fonctionnement de Bootstrap.

Configuration des chemins necessaire à la compilation sass

Pour informer Jekyll de l’endroit ou sont les fichiers sass qui devra utiliser pour créer les feuilles CSS, nous devons modifier le fichier _config.yml en ajoutant les lignes suivantes :

sass:
    load_paths:
        - _sass
        - node_modules
exclude: []

Ajout du dossier _layout et de la page home.html

Par défaut , Jekyll ira cherche les layouts (qui sont appelés en début d’un post Markdown) dans un dossier à la racine _layouts. Un fois crée, on y ajoutera un template home.html

mdkir _layouts
cd _layouts
touch home.html

Le fichier home.html sera le template html appele par chaque post. Pour que le navigateur charge les scripts JS et les CSS Bootstrap, on devra insérer une lien vers /assets/main.css au début du fichier et les scripts en fin de fichier après le footer, comme dans l’exemple ci-dessous :

<!DOCTYPE html>
<html lang="fr">

<head>
  <title>City Travels/title>
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="/assets/main.css">

</head>

<body>
  <!-- Navigation -->
  <!-- Page Header -->
  <!-- Main Content -->
  <!-- Footer -->
  <script src="/node_modules/jquery/dist/jquery.min.js"></script>
  <script src="/node_modules/popper.js/dist/popper.min.js"></script>
  <script src="/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
</body>

</html>

Ce code n’étant un template valide, puisqu’il manque le contenu, nous allons donner un example basic complet :

Example de template Bootstrap pour jekyll

Bootstrap fournit une grande quantité d’exemple depuis son site internet : https://getbootstrap.com/docs/4.0/examples/

Une fois que nous avons téléchargé et dézippé le code source de bootstrap 4, nous allons récupérer les fichiers index.htlm et album.css dans le dossier : /bootstrap-4.0.0/docs/4.0/examples/album. Comme nous souhaitons faire un site “Photos de voyages”, cette structure s’y prete bien. Deux étapes sont alors necessaire pour utiliser ce theme avec Jekyll :

1. Ajouter la feuille de style album.css au fichier /assets/main.scss tel que :

---
---

@import "variables";
@import "bootstrap/scss/bootstrap";
@import "custom/album";

.content {
  font-size: $custom-font-size;
}

et copier album.css dans le dossier assets/custom en le renommant _album.scss . Sass et Jekyll se chargeront automatiquement de la compilation en CSS.

2. Intégrer le contenu du fichier index.html au template /_layout/home.html comme :

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../../../favicon.ico">

    <title>Graine Digitale</title>

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="/assets/main.css">
  </head>

  <body>

    <header>
      <div class="collapse bg-dark" id="navbarHeader">
        <div class="container">
          <div class="row">
            <div class="col-sm-8 col-md-7 py-4">
              <h4 class="text-white">About</h4>
              <p class="text-muted">Ressources, astuces et mémos numériques</p>
            </div>
            <div class="col-sm-4 offset-md-1 py-4">
              <h4 class="text-white">Contact</h4>
              <ul class="list-unstyled">
                <li><a href="#" class="text-white">Follow on Twitter</a></li>
                <li><a href="#" class="text-white">Like on Facebook</a></li>
                <li><a href="#" class="text-white">Email me</a></li>
              </ul>
            </div>
          </div>
        </div>
      </div>
      <div class="navbar navbar-dark bg-dark box-shadow">
        <div class="container d-flex justify-content-between">
          <a href="#" class="navbar-brand d-flex align-items-center">
            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"></path><circle cx="12" cy="13" r="4"></circle></svg>
            <strong>Graine Digitale</strong>
          </a>
          <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarHeader" aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
        </div>
      </div>
    </header>

    <main role="main">

      <section class="jumbotron text-center">
        <div class="container">
          <h1 class="jumbotron-heading">Album example</h1>
          <p class="lead text-muted">Something short and leading about the collection below—its contents, the creator, etc. Make it short and sweet, but not too short so folks don't simply skip over it entirely.</p>
          <p>
            <a href="#" class="btn btn-primary my-2">Main call to action</a>
            <a href="#" class="btn btn-secondary my-2">Secondary action</a>
          </p>
        </div>
      </section>

      <div class="album py-5 bg-light">
        <div class="container">

          <div class="row">
            <div class="col-md-4">
              <div class="card mb-4 box-shadow">
                <img class="card-img-top" data-src="holder.js/100px225?theme=thumb&bg=55595c&fg=eceeef&text=Thumbnail" alt="Card image cap">
                <div class="card-body">
                  <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <div class="d-flex justify-content-between align-items-center">
                    <div class="btn-group">
                      <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                      <button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
                    </div>
                    <small class="text-muted">9 mins</small>
                  </div>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="card mb-4 box-shadow">
                <img class="card-img-top" data-src="holder.js/100px225?theme=thumb&bg=55595c&fg=eceeef&text=Thumbnail" alt="Card image cap">
                <div class="card-body">
                  <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <div class="d-flex justify-content-between align-items-center">
                    <div class="btn-group">
                      <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                      <button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
                    </div>
                    <small class="text-muted">9 mins</small>
                  </div>
                </div>
              </div>
            </div>
            <div class="col-md-4">
              <div class="card mb-4 box-shadow">
                <img class="card-img-top" data-src="holder.js/100px225?theme=thumb&bg=55595c&fg=eceeef&text=Thumbnail" alt="Card image cap">
                <div class="card-body">
                  <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <div class="d-flex justify-content-between align-items-center">
                    <div class="btn-group">
                      <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                      <button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
                    </div>
                    <small class="text-muted">9 mins</small>
                  </div>
                </div>
              </div>
            </div>

            <div class="col-md-4">
              <div class="card mb-4 box-shadow">
                <img class="card-img-top" data-src="holder.js/100px225?theme=thumb&bg=55595c&fg=eceeef&text=Thumbnail" alt="Card image cap">
                <div class="card-body">
                  <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
                  <div class="d-flex justify-content-between align-items-center">
                    <div class="btn-group">
                      <button type="button" class="btn btn-sm btn-outline-secondary">View</button>
                      <button type="button" class="btn btn-sm btn-outline-secondary">Edit</button>
                    </div>
                    <small class="text-muted">9 mins</small>
                  </div>
                </div>
              </div>
            </div>

    </main>

    <footer class="text-muted">
      <div class="container">
        <p class="float-right">
          <a href="#">Back to top</a>
        </p>
        <p class="copyright text-muted">Copyright &copy;<a href="http://www.grainedigitale.com" >Graine Digitale</a> 2018</p>
      </div>
    </footer>
    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="/node_modules/jquery/dist/jquery.min.js"></script>
    <script src="/node_modules/popper.js/dist/popper.min.js"></script>
    <script src="/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
  </body>
</html>

On peut voir que le template fonctionne bien, mais que le template n’eploite pas toutes les fonctionnalités de Jekyll permettant de le rendre générique. On peut voir en effet que les le contenu des <div> n’est pas configuré , Elles se répetent dans le corps de la page et qu’il n’y a aussi aucune image . Nous allons devoir le le modifier à l’aide de Liquid. Par ou commencer ? Par le début !

Ajouter une barre de navigation responsive

Le temple album ne dispose pas de barre de menu, j’aurai souhaité en avoir une qui affiche les pages du site et qui soit reponsive avec un peu de Javascript. Comme je n’ai pas beaucoup de temps, je vais chercher un exemple de barre de menu déja développée. Il y a beaucoup exemples de navbar sur ce site par exemple : https://bootsnipp.com/tags/navbar

Sources utiles