Le ménage de printemps est arrivé. J’ai refait entièrement mon site perso (ngaumont.fr) ainsi que la partie blog (note.ngaumont.fr) pour fusionner le tout.

Site fait main mais peu extensible

J’aimais beaucoup l’ancien site. Je l’avais fait entièrement à la main sans aucun framework. C'était de l’HTML, du CSS pur (pas sass ou less) et 56 lignes de javascript pour gérer le single page et le masquage de sections. Ce JavaScript était optionnel et sa désactivation ne gênait pas la lecture du site. Mon site était donc en partie lowtech, malgré la présence de quelque images et pdf (thèse et présentation) un peu lourd.

Cependant, cette organisation est problématique dans le cas d’ajout de contenu, car le concept de single page n’est plus adapté. La personne qui visite le site se retrouve à télécharger une énorme page pour n’afficher que quelques sections. Ajouter du contenu pour transformer le site en une sorte de blog complique également la partie JavaScript pour gérer la navigation et l’UX.

Malgré ces défauts, j’avais choisi de faire une page unique avec un peu jacascript pour une raison principale : cohérence graphique et moins de duplication de contenu. Je n’avais qu’un seul endroit ou était défini mon header, mon footer et mon menu de navigation. Le fait de créer une page unique autosuffisante limite aussi le nombre d’outils à apprendre et à maintenir (Coucou wordpress). En cas de changement de serveur, je n’ai qu'à déplacer mon dossier chez le nouvel hébergeur et à configurer apache2 ou nginx.

Un blog un peu trop usine à gaz

Après de long moment d’hésitation, j’ai finalement créé une partie blog à part avec ghost. Je pensais écrire des posts en MarkDown et laisser ghost compiler le tout (une seule fois) en HTML, CSS et JS. Au final, je me retrouvais avec un système avec un docker-compose tournant en permanence sur mon serveur et, comme le contenu sur ghost est stocké dans du sqlite, je n’avais pas non plus accès au contenu MarkDown ou HTML généré.

Ghost fait beaucoup d’effort pour que la personne qui écrit du contenu ne se pose pas trop de questions. C’est pratique pour se lancer, mais je commençais à me demander comment j’allais faire pour personnaliser certains aspects du site. Comment faire pour avoir accès au CSS ou ajouter du contenu HTML relativement simplement ? Par exemple, je n’aimais pas que ghost me “force” la main pour créer des card Twitter ou Facebook pour mes postes.

Hugo pour de la génération vraiment statique

Face à ce constat, j’ai voulu tester un autre générateur de site statique et essayer de réunir la partie vitrine et blog de mon site. Il y a de nombreuses ressources en lignes comme staticgen. Pour ma part, mon cœur a balancé entre: hugo, gastby, pelican ou zola.

J’ai au final éviter les solutions JS et choisi hugo pour sa popularité et documentation. Il me semble, qu’avec des solutions comme gastby et next.js, il est plus difficile de ne pas s’emprisonner avec du JavaScript obligatoire coté client. Je n’ai rien contre un traitement JS coté serveur, mais pour le client je préfère que la dépendance soit optionnel.

J’ai donc parcouru les thèmes existants. Après avoir testé quelques thèmes, je suis resté sur ghostwriter. Il me semblait relativement simple à comprendre et à personnalisé si besoin. Il n’y a pas de gestion poussée des cards ou autre fonctionnalités inutiles à mon niveau. Je peux cependant assez facilement modifier l’affichage avec les partials et les shortcodes.

J’ai par exemple pu dans la partie expérience ajouter les dates de début et de fin de chaque expérience professionnelle. J’ai aussi pu modifier la partie publications. La liste des publications est généré à partir de fichiers .bib et de quelques métadonnées. La mise à jour de cette liste est maintenant beaucoup plus simple et robuste. La partie des publications dans les journaux internationnaux est défini de la manière suivante:

## Journal international

{{< publication "InternationalJournal" >}}

publication fait référence au shortcode que j’ai défini de la manière suivante:

{{ $data := index .Site.Data (.Get 0) }}
{{ $all_additional := index .Site.Data "publications" }}

{{ range $data }}
  {{ $year := index (index (index .issued "date-parts") 0) 0 }}
  {{ $.Scratch.Add "enriched-publi" (slice (dict "publi" . "year" $year)) }}
{{ end }}


<ol class="publi-sub-list">
{{ range sort ($.Scratch.Get "enriched-publi") ".year" "desc"}}
   {{ $authors := apply .author "partial" "publi-author" ".publi"}}
   {{ $year := .year}}
   {{ $urls := slice }}
   {{ with .publi.DOI}}
      {{$urls = $urls | append (printf "<a href=\"https://dx.doi.org/%s\">%s</a>" . .)}}
   {{ end }}
   {{ with .publi.URL}}
      {{$urls = $urls | append (printf "<a href=\"%s\"> %s</a>" . "référence")}}
   {{ end }}
   <li class="single-publi">
     <span class="title">{{.publi.title | safeHTML }}</span>.
     <span clas="authors">{{  delimit $authors ", " " and " }} </span>In {{ index .publi "container-title" }}, {{ $year }}{{with .publi.volume}}, ({{.}}){{end}}{{with .publi.issue}}, ({{.}}){{end}}.
     {{ with index $all_additional .publi.id}}
      {{ with .acceptance}}
        <span class="acceptance">Taux d'acceptation : {{ . }}.</span>
      {{ end }}
      {{ with .slide}}
         {{$urls = $urls | append (printf "<a class=\"publi-slide\" href=\"%s\"> %s</a>" (absURL .)  "slides")}}
      {{ end }}
      {{ with .code}}
         {{$urls = $urls | append (printf "<a class=\"publi-slide\" href=\"%s\"> %s</a>" (absURL .)  "code")}}
      {{ end }}
     {{ end }}
     {{with $urls}} {{delimit $urls ", "}}.{{end}}
   </li>
{{ end }}
</ol>

C’est un peu verbeux et sûrement améliorable, mais j’ai pu le faire et avoir le résultat que je voulais.