Créer un Epic (Parcours pédagogique)#
Ce guide vous accompagne dans la création d'un Epic, une collection de slides formant un parcours pédagogique cohérent sur PlayLab42.
Qu'est-ce qu'un Epic ?#
Un Epic est l'unité de publication dans le système Parcours :
- Collection ordonnée de slides (1 à N)
- Possède ses propres métadonnées (titre, auteur, vignette, etc.)
- Organisé en sections optionnelles
- Classé dans une hiérarchie et taggé pour le filtrage
Caractéristiques :
- 100% statique (compatible GitHub Pages)
- Slides en HTML ou Markdown (conversion automatique)
- Support des médias (images, vidéos, audio)
- Progression utilisateur sauvegardée
Prérequis#
- Connaissances de base en HTML et/ou Markdown
- Docker installé (
make servepour tester)
Structure d'un Epic#
parcours/epics/mon-epic/
├── epic.json # Manifest de l'epic (obligatoire)
├── thumbnail.png # Vignette (recommandée)
├── assets/ # Médias partagés
│ ├── images/
│ │ └── schema.png
│ └── videos/
│ └── demo.mp4
└── slides/
├── 01-intro/
│ ├── slide.json # Métadonnées de la slide
│ └── index.html # ou index.md (contenu)
└── 02-concepts/
├── slide.json
└── index.md
Étapes#
1. Créer le dossier de l'Epic#
mkdir -p parcours/epics/mon-epic/slides/01-intro
Convention de nommage : kebab-case pour le nom du dossier.
2. Créer le manifest epic.json#
{
"id": "mon-epic",
"title": "Mon Premier Epic",
"description": "Description courte (1-3 phrases) de l'epic.",
"hierarchy": ["playlab42"],
"tags": ["howto", "debutant"],
"metadata": {
"author": "Votre Nom",
"created": "2025-01-15",
"duration": "15 min",
"difficulty": "beginner",
"language": "fr"
},
"icon": "📚",
"thumbnail": "thumbnail.png",
"content": [
{ "id": "01-intro" }
]
}
Champs du manifest#
| Champ | Obligatoire | Description |
|---|---|---|
id | ✅ | Identifiant unique = nom du dossier |
title | ✅ | Titre affiché |
description | ✅ | Description courte (1-3 phrases) |
hierarchy | ✅ | Position dans la hiérarchie (["playlab42"] ou ["autres"]) |
tags | ✅ | Tags pour le filtrage |
metadata.author | ✅ | Auteur de l'epic |
metadata.created | ✅ | Date de création (ISO 8601) |
metadata.updated | Date de dernière modification | |
metadata.duration | Durée estimée ("15 min", "2h") | |
metadata.difficulty | "beginner", "intermediate", "advanced" | |
metadata.language | Langue ("fr", "en") | |
icon | Emoji pour l'icône | |
thumbnail | Chemin vers la vignette (380x180px, 19:9, < 50KB) | |
content | ✅ | Liste des slides et sections |
draft | true pour ne pas publier |
3. Créer les slides#
Chaque slide est un dossier avec slide.json et un fichier de contenu.
Format slide.json#
{
"id": "01-intro",
"title": "Introduction",
"icon": "👋"
}
| Champ | Obligatoire | Description |
|---|---|---|
id | ✅ | Identifiant = nom du dossier |
title | ✅ | Titre affiché dans le menu |
icon | Emoji pour l'icône | |
description | Description courte | |
duration | Durée estimée |
Contenu HTML (index.html)#
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Introduction - PlayLab42</title>
<link rel="stylesheet" href="../../../../../lib/theme.css">
<link rel="stylesheet" href="../../../../_shared/slide-base.css">
<script type="module">
import { initTheme } from '../../../../../lib/theme.js';
initTheme();
</script>
</head>
<body>
<article class="slide">
<h1>Introduction</h1>
<p>Bienvenue dans ce parcours !</p>
<h2>Objectifs</h2>
<ul>
<li>Premier objectif</li>
<li>Deuxième objectif</li>
</ul>
</article>
</body>
</html>
Contenu Markdown (index.md) - Recommandé#
# Introduction
Bienvenue dans ce parcours !
## Objectifs
- Premier objectif
- Deuxième objectif
## Code d'exemple
```javascript
function hello() {
console.log("Hello World!");
}
Note : Les slides Markdown sont converties automatiquement en HTML lors du build.
**Avantages du Markdown :**
- Plus simple et rapide à écrire
- Coloration syntaxique automatique pour le code
- Conversion automatique lors du `build:parcours`
**Source et sorties générées :**
- `index.md` est la source ; chaque build régénère `index.html` avec le Markdown,
le titre de `slide.json` et le template courant `parcours/_shared/slide-template.html`.
- La sortie commence exactement par `<!-- playlab42:generated-from-index.md -->`
suivi d'un saut de ligne LF à l'écriture. La reconnaissance accepte LF ou CRLF
(par exemple après un checkout Git), mais uniquement ce commentaire exact
en première ligne. Ne pas modifier cette sortie ni retirer son marqueur :
les modifications manuelles seraient perdues au prochain build.
- Un `index.html` auteur seul reste intact et ne nécessite pas le template.
- Une paire `index.md` / `index.html` sans marqueur est ambiguë : le build échoue,
sans écraser le HTML ni remplacer `data/parcours.json`. Aucun choix de source
ne dépend de dates, du contenu ou du champ optionnel `format`.
- Pour migrer une ancienne sortie sans marqueur, relire et sauvegarder le HTML
hors des sources, puis supprimer **uniquement cette sortie** et reconstruire
depuis `index.md`. Si le HTML est la source à conserver, retirer `index.md`.
- Un template absent avec du Markdown, ou un HTML marqué dont `index.md` a
disparu, fait échouer le build. Pour adopter volontairement une sortie comme
HTML auteur, retirer le Markdown et le marqueur après revue.
### 4. Organiser avec des sections
Pour structurer un epic avec plusieurs slides, utilisez des sections :
```json
{
"id": "mon-epic",
"title": "Mon Epic",
"description": "...",
"hierarchy": ["playlab42"],
"tags": ["tutorial"],
"metadata": {
"author": "Auteur",
"created": "2025-01-15"
},
"content": [
{
"id": "introduction",
"title": "Introduction",
"icon": "👋",
"content": [
{ "id": "01-bienvenue" },
{ "id": "02-prerequis" }
]
},
{
"id": "pratique",
"title": "Mise en pratique",
"icon": "🛠️",
"content": [
{ "id": "03-exercice-1" },
{ "id": "04-exercice-2" }
]
},
{ "id": "05-conclusion" }
]
}
5. Marquer des slides optionnelles#
{
"content": [
{ "id": "01-intro" },
{ "id": "02-avance", "optional": true },
{ "id": "03-conclusion" }
]
}
Une section entière peut aussi être optionnelle :
{
"id": "bonus",
"title": "Pour aller plus loin",
"icon": "🚀",
"optional": true,
"content": [
{ "id": "bonus-01" },
{ "id": "bonus-02" }
]
}
6. Ajouter des médias#
Structure recommandée#
mon-epic/
├── assets/
│ ├── images/
│ │ ├── schema.png
│ │ └── capture.jpg
│ └── videos/
│ └── demo.mp4
└── slides/
└── 01-intro/
└── index.html
Référencer dans HTML#
<!-- Image depuis les assets de l'epic -->
<img src="../../assets/images/schema.png" alt="Schéma explicatif">
<!-- Vidéo -->
<video controls>
<source src="../../assets/videos/demo.mp4" type="video/mp4">
</video>
Référencer dans Markdown#

<!-- Pour vidéo/audio, utiliser HTML inline -->
<video controls src="../../assets/videos/demo.mp4"></video>
Limites de taille#
| Élément | Limite |
|---|---|
| Image | < 500KB |
| Vidéo | < 10MB |
| Audio | < 5MB |
| Vignette | 380x180px (19:9), < 50KB |
| Total Epic | < 50MB |
7. Générer le catalogue#
make build-parcours
Le build :
- Valide les manifests
- Convertit les slides Markdown en HTML
- Génère
data/parcours.json
8. Tester#
make serve
# Ouvrir http://localhost:5242
# Naviguer vers l'onglet "Parcours"
Exemples#
Epic minimal (1 slide Markdown)#
parcours/epics/exemple-article/
├── epic.json
└── slides/
└── 01-introduction/
├── slide.json
└── index.md
epic.json
{
"id": "exemple-article",
"title": "Mon Article",
"description": "Un article simple.",
"hierarchy": ["autres"],
"tags": ["article"],
"metadata": {
"author": "Moi",
"created": "2025-01-15"
},
"content": [
{ "id": "01-introduction" }
]
}
slides/01-introduction/slide.json
{
"id": "01-introduction",
"title": "Introduction"
}
slides/01-introduction/index.md
# Introduction
Bienvenue dans mon article !
## Points clés
- Point 1
- Point 2
- Point 3
Epic complet avec sections#
Voir l'epic hello-playlab42 dans parcours/epics/hello-playlab42/ pour un exemple complet avec :
- Vignette
- Sections multiples
- Slides HTML et Markdown
- Assets
Checklist de validation#
Avant de publier votre epic, vérifiez :
-
epic.jsoncontient tous les champs obligatoires - Chaque slide référencée dans
contentexiste dansslides/ - Chaque slide a un
slide.jsonet unindex.htmlouindex.md - Les médias référencés existent
- La vignette fait 380x180px (19:9) et < 50KB (si sp\u00e9cifi\u00e9e)
-
make build-parcoursne génère pas d'erreurs - L'epic s'affiche correctement dans le viewer
Bonnes pratiques#
Contenu#
- Titre clair : Le titre doit indiquer le sujet du parcours
- Description utile : 1-3 phrases décrivant ce que l'utilisateur va apprendre
- Slides courtes : Une idée principale par slide
- Progression logique : Du simple au complexe
Structure#
- Préfixes numériques :
01-intro,02-concepts,03-pratique - Sections pour 4+ slides : Organiser en groupes logiques
- Slides optionnelles : Pour le contenu avancé ou bonus
Médias#
- Optimiser les images : WebP ou PNG compressé
- Alt text : Toujours fournir des descriptions
- Vidéos courtes : < 2 minutes, ou utiliser YouTube/Vimeo
Style#
- Utiliser les CSS :
slide-base.csspour la cohérence - Variables CSS :
var(--color-accent), etc. - Responsive : Tester sur mobile
Markdown supporté#
| Fonctionnalité | Syntaxe |
|---|---|
| Titres | # H1, ## H2, ### H3 |
| Gras | **texte** |
| Italique | *texte* |
| Code inline | `code` |
| Bloc de code | ```langage ``` |
| Listes | - item ou 1. item |
| Liens | [texte](url) |
| Images |  |
| Citations | > citation |
| Tableaux | GFM |
| Séparateurs | --- |
La coloration syntaxique est automatique pour les blocs de code avec un langage spécifié (javascript, python, html, etc.).
Voir aussi#
- Architecture - Vue d'ensemble de la plateforme
- Spec Parcours (source Markdown) - Spécification technique complète
- parcours/README.md (source Markdown) - Documentation technique