10 minute read

@wildagsx

đŸ€— Non je ne quitte pas Noti.st car c’est un mauvais outil

Cela me semblait utile de commencer par indiquer que ce blog post n’est pas pour dire que Noti.st est un mauvais outil. Bien au contraire, aprĂšs 3 ans d’utilisation je n’ai pas grand chose Ă  lui reprocher, il fait trĂšs bien le travail. Pour vous expliquer ce qu’est Noti.st je pense que le texte d’accueil du site rĂ©sume parfaitement son but:

Notist is a place to build your public speaking portfolio. A place to share your slides, but also to collate feedback, tweets, photos, resources and everything to create a permanent history of your speaking events.

Si vous voulez voir ce que cela donne voici mon compte publique : https://noti.st/philippart-s

đŸ€š Mais alors pourquoi partir de Noti.st ?

Pour plusieurs raisons, mais la principale est le fameux “vendor locking”. En effet, tout ce que j’ai mis dans Noti.st n’est pas rĂ©cupĂ©rable, je peux rĂ©cupĂ©rer la liste de mes talks mais pas les Ă©lĂ©ments que j’ai uploadĂ©s (titres, localisations, slides, liens, 
). Ce qui, le jour oĂč je ne souhaite plus payer mon abonnement (> 100$ par an) ou tout simplement arrĂȘter peut ĂȘtre problĂ©matique. Soit j’ai tout perdu, soit je vais galĂ©rer avec pleins d’actions manuelles pour le faire (spoiler on en parlera lors de la partie migration đŸ˜±).

Et autre raison : cela faisait un petit moment que je me disais qu’il y avait moyen de dĂ©velopper un truc au sein mĂȘme de mon blog au final 
 Oui mĂȘme pour moi qui suit trĂšs loin d’ĂȘtre un dĂ©veloppeur front (c’est pour cela que j’utilise Jekyll 😇).

📚 Bon on y va ? C’est quoi les specs ?

Mon but : faire le moins d’actions possibles lorsque je dois rajouter un talk. J’aurai donc un fichier de donnĂ©es global oĂč je retrouverai mes informations de base pour un talk : nom de la confĂ©rence, date, talk, slides, replay, source, 
 Des templates pour gĂ©nĂ©rer un maximum de choses, idĂ©alement je ne veux pas Ă  avoir Ă  crĂ©er un blog post aprĂšs chaque confĂ©rence mais juste une nouvelle entrĂ©e dans mon fichier de donnĂ©es. Ce dernier point va ĂȘtre important dans certains choix par la suite.

Bien entendu, le tout intĂ©grĂ© dans Jekyll afin de facilement l’avoir dans mon blog.

Bonus attendus :

  • une gestion as code
  • une gestion du cycle de vie dans Git
  • une modification simple car via des templates
  • la dĂ©couverte d’une utilisation avancĂ©e de Jekyll

💿 Les donnĂ©es

Le choix pour mes donnĂ©es de confĂ©rences a Ă©tĂ© assez rapide, YAML. Parce que on ne va pas se mentir, mĂȘme si on dit que l’on n’aime pas ça, c’est quand mĂȘme bien pratique et pas trop verbeux. Jekyll permet de manipuler et d’accĂ©der nativement aux donnĂ©es dans un fichier YAML avec le moteur de templating Liquid.

A ce jour la structure d’une entrĂ©e YAML pour une confĂ©rence est la suivante:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
conf-2025:
 name: conf
 post-date: 2025-01-22
 date: 22 au 25 janvier 2025 
 excerpt: "Liste des talks donnés lors de Conf 2025"
 categories: Conférences
 tags:
   - Slides
   - Replays
 talks:
  - title: "blabla"
    location: Ville (đŸ‡«đŸ‡·)
    language: Français
    date: Mercredi 22 janvier 2025
    time: 14h00 - 17h00
    duration: 3h mins
    abstract: |
      blabla
    source: xxx
    slides: xxx
    replay: xxx

â„č Pour que Jekyll puisse les utiliser il vous suffit de les dĂ©poser dans le rĂ©pertoire _data de votre blog.

đŸžïž Le layout, Ă©viter de rĂ©inventer la roue

Une fois ces donnĂ©es créées, il faut maintenant les afficher, pour cela rien de plus simple avec Jekyll et le moteur de templating Liquid, il est trĂšs simple d’ajouter du dynamisme et de la gĂ©nĂ©ricitĂ© dans les blog posts.

Et cerise sur le gateau, Jekyll vient avec un mĂ©canisme de layouts pour faciliter la mise en page de vos articles. Et il est aussi possible d’utiliser Liquid dans un layout 😉.

Du coup, pour créer un nouveau layout, il suffit de créer mon fichier conference.html dans le répertoire _layouts de mon blog:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
---
layout: archive
classes: wide
categories:
- Conférences
tags:
- Slides
- Replays
---

{{ content }}

{% for conferences in site.data.conferences %}
{% assign conferenceFile = conferences[0] %}
{% assign conference = site.data.conferences[conferenceFile] %}

{% if conference[page.conference-name] %}
{% for talk in conference[page.conference-name].talks %}

<h2> {{talk.title}} </h2>

📍{{talk.location}} / đŸ—Łïž {{talk.language}} / đŸ—“ïž {{talk.date}} / ⏰ {{talk.time}} / 🕒 {{talk.duration}}

{% capture notice-2 %}
{{talk.abstract}}
{% endcapture %}

<div class="notice">{{ notice-2 | markdownify }}</div>

{% if talk.source %}📚 <a href="{{talk.source}}">Code source</a> / {% endif %} {% if talk.slides %}🌠
<a href="{{talk.slides}}">Slides</a> 
{% endif %} {% if talk.replay %}/ đŸŽ„ <a href="{{talk.replay}}">Replay</a>{% endif %}

{% endfor %}
{% endif %}
{% endfor %}

Ce qu’il faut retenir :

  • la premiĂšre partie (entre le ---) permet d’utiliser un layout de base si on le souhaite,
  • les {{ }} permettent d’accĂ©der Ă  des variables prĂ©dĂ©finies, comme content ou créées, comme talk
  • {{ content }} reprĂ©sente le contenu du blog post créé qui utilisera ce layout et sera injectĂ© Ă  cet endroit du layout
  • les {% %} permettent d’ajouter des instructions de flow

📝 CrĂ©er les articles Ă  partir du layout

A ce stade je peux utiliser mon layout dans un article fraßchement créé, par exemple pour Devoxx France:

1
2
3
4
5
6
7
8
9
10
11
---
layout: conference
title: Talks donnés à Devoxx France
date: 2025-04-16
permalink: /talks/devoxx-fr-2025
excerpt: Liste des talks donnés lors de Devoxx France 2025
categories: Conférences
tags: 
 - ["Slides", "Replays"]
conference-name: devoxx-fr-2025
---

Cela me gĂ©nĂšre l’article suivant: @wildagsx

C’est bien 
 Mais c’est dommage de devoir crĂ©er un fichier Ă  chaque talk pour qu’au final il soit vide avec juste l’en-tĂȘte renseignĂ©e.

Il doit bien avoir un moyen d’automatiser ça, d’autant que les donnĂ©es sont prĂ©sentes dans le fichier de donnĂ©es YAML prĂ©cĂ©demment créé.

⚙ GĂ©nĂ©rer les articles avec un plugin

Jekyll utilise des plugins, soit communautaires, soit locaux. C’est le deuxiĂšme type qui va nous intĂ©resser, crĂ©er un plugin local. En effet, pour gĂ©nĂ©rer des pages, on va crĂ©er un plugin de type generator (logique 😉). Et comme il est petit, pas besoin de le packager, pour cela il suffit de le mettre dans le rĂ©pertoire _plugins de notre site.

C’est du Ruby et voyons à quoi il ressemble :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
require 'jekyll'
require 'fileutils'

module Jekyll
  class ConferenceGenerator < Generator
    safe true

    def generate(site)
      puts "---------- ConferenceGenerator started ----------"
       if (!defined?@render_count)
          @render_count = 1
       end

       if @render_count < 1
         Jekyll.logger.info('already fetched data')
         return
       end

       conferencesFilesKey = site.data['conferences'].keys.select { |key| key.include?('conferences') }
       conferencesFilesKey.each do |key|
         Jekyll.logger.info("Processing #{key}")

          conferences = site.data['conferences'][key]

          if conferences
            conferences.each do |conference_id, details|
              post_path = File.join('_posts', "#{details['post-date']}-#{conference_id}-talks.markdown")

              post_data = {
                'layout' => 'conference',
                'title' => "Talks donnés à #{details['name']}",
                'date' => details['post-date'],
                'permalink' => "/talks/#{conference_id}",
                'excerpt' => details['excerpt'],
                'categories' => "#{details['categories']}",
                'tags' => "\n - #{details['tags']}",
                'conference-name' => conference_id
              }
              
              post_content = "---\n"
              post_content += post_data.map { |key, value| "#{key}: #{value}" }.join("\n") + "\n"
              post_content += "---\n"

              # Write the post file
              FileUtils.mkdir_p(File.dirname(post_path))
              File.write(post_path, post_content)

              puts "Generated post: #{post_path}"
            end
          else
            puts "No conferences data found in site.data"
          end
          Jekyll.logger.info('Data fetched successfully.')
          @render_count = @render_count - 1
          puts "---------- ConferenceGenerator finished ----------"
        end
      end
  end
end

Rien de bien compliqué ici :

  • l10 -> l17 : c’est juste un garde fou (pas trĂšs Ă©lĂ©gant) pour Ă©viter Ă  Jekyll de boucler indĂ©finiment en mode watch. Le mode watch rĂ©gĂ©nĂšre l’ensemble du site et appelle les plugins Ă  chaque modification de fichier et comme le plugin Ă  chaque exĂ©cution gĂ©nĂšre des fichiers c’est un cercle sans fin 😉. Il faudra que je trouve une maniĂšre plus Ă©lĂ©gante de le gĂ©rer.
  • l19 : j’utilise uniquement les fichier YAML qui ont des donnĂ©es sur les confĂ©rences (ces fichiers commencent par conferences)
  • l20 -> l42: j’itĂšre pour chaque confĂ©rence et je fabrique l’en-tĂȘte
  • l45 -> l46: crĂ©ation physique du fichier avec les donnĂ©es prĂ©parĂ©es (pour me repĂ©rer, les articles gĂ©nĂ©rĂ©s ont l’extension markdown et ceux Ă©crits Ă  la main md)

Et voilĂ  avec ce script Ă  chaque modification dans un fichier YAML de donnĂ©es de confĂ©rences, les articles correspondants sont créés 😎.

🍰 Cerise sur le gñteau, une page pour lister les talks

Comme j’ai les donnĂ©es qui servent Ă  crĂ©er les pages unitaires, il est assez facile de crĂ©er une page qui liste l’ensemble de mes confĂ©rences regroupĂ©es par annĂ©e:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
---
title: "Conférences"
permalink: /conferences/
classes: wide
excerpt: "Liste des conférences avec les ressources (slides, vidéos, ...)"
#author_profile: false
categories:
- Conférences
tags:
- Slides
- Replays
---

Ici vous trouverez l'ensemble des conférences auxquelles j'ai participé et que j'ai présentées. 

Vous pouvez aussi retrouver la [liste des sujets]({{ site.baseurl }}/talks) que j'ai donnés en conférence.

<style>
  table {
    width: 100%;
    height: 100%;
    display: table;
  }

  th,
  td {
    border: 0px solid #000;
    padding: 10px;
    text-align: center;
    vertical-align: middle;
  }

  th {
    background-color: #f2f2f2;
  }
</style>

<table>
  {% for conferences in site.data.conferences reversed %}
    {% assign conferenceFile = conferences[0] %}

  <tr>
    <th colspan="3">
      <h1>  {{ conferenceFile | split: "-" | last }} </h1>
    </th>
  </tr>

  {% for conference in site.data.conferences[conferenceFile] %}
  <tr>
    <td style="width: 35%; text-align: left;">
      {{ conference[1].name}}
    </td>
    <td style="width: 35%;">
      đŸ—“ïž {{ conference[1].date }} đŸ—“ïž
    </td>
    <td style="width: 30%;">
      đŸŽ€ <a href="{{ site.baseurl }}/talks/{{ conference[0] }}">
        Liste des talks
      </a> đŸŽ€
    </td>
  </tr>
  {% endfor %}
  {% endfor %}
</table>

📋 Il en reste une 


J’ai aussi créé une page qui liste les talks que j’ai donnĂ© et pour chaque talk la confĂ©rence avec le lien vers cette confĂ©rence. Si j’ai toutes les donnĂ©es, elles se trouvent dans l’ensemble des fichiers YAML. Cela demanderait Ă  faire une analyse croisĂ©e et des group by entre les donnĂ©es des fichiers, pas infaisable mais crĂ©er la page Ă  la main a Ă©tĂ© moins long 😜.

Cette page se trouve ici et son code ici.

Peut-ĂȘtre une amĂ©lioration dans le futur 


đŸ„ł En conclusion

Ce qui m’a pris le plus de temps a Ă©tĂ© de reporter l’ensemble de mes talks depuis Noti.st vers mon blog. Pas d’export des donnĂ©es donc tout Ă  la main talk par talk, pour plus de 50 talks j’ai dĂ» y passer 3 Ă  4h.

Maintenant que c’est fait, rajouter un talk c’est ajouter une entrĂ©e dans le fichier YAML, soit pas plus de 2-3 minutes !

Pour voir ce que cela donne :

  • la page qui liste les confĂ©rences avec un lien vers chaque article qui indique les talks avec leurs dĂ©tails
  • la page qui liste les talks avec la liste des confĂ©rences oĂč ils ont Ă©tĂ© donnĂ©s (avec un lien vers l’article de la dite confĂ©rence)
  • un exemple d’article gĂ©nĂ©rĂ©

La suite ?

Certainement ajouter la partie rĂ©seau social / photos / la possibilitĂ© de mettre plusieurs liens vers du code source / une carte / 
 Au final j’ai juste Ă  modifier mes templates, rajouter les donnĂ©es dans les YAML et ce sera effectif 😉.

Si vous ĂȘtes arrivĂ©s jusque lĂ  merci de m’avoir lu et si il y a des coquilles n’hĂ©sitez pas Ă  me faire une issue ou PR 😊.

Comments