Skip to Content

Chapitre 3.4 — Resources & fichiers

⏱️ TL;DR — Le bloc <resources> est l’inventaire du paquet : la liste des fichiers, groupés par <resource>. Chaque <resource> porte un identifier (celui que l’arbre référence), un type="webcontent", un adlcp:scormType (sco ou asset), et — pour un SCO — un href (la page de lancement). À l’intérieur, chaque fichier utilisé est déclaré par un <file href="…"/>, et les ressources partagées se factorisent avec <dependency identifierref="…"/>. Tous les chemins sont relatifs à la racine du .zip, sensibles à la casse et aux slashs : c’est là que se logent les bugs de « fichier introuvable ».

🎯 Objectifs

  • Écrire une <resource> complète et correcte (SCO et asset).
  • Comprendre le rôle exact de href vs <file> et pourquoi les deux existent.
  • Factoriser des fichiers partagés avec <dependency>.
  • Maîtriser les chemins relatifs et éviter les pièges de casse et de slash.
  • Vérifier qu’aucun fichier n’est oublié dans l’inventaire.

L’anatomie d’une resource

Une <resource> décrit un lot de fichiers et, si c’est un SCO, par quel fichier on le lance. Ses attributs :

AttributRôleExemple
identifierL’ID unique que l’arbre <item> référence via identifierref.RES_PHISHING
typeLe type de ressource. En SCORM, quasi toujours webcontent.webcontent
adlcp:scormTypeSCO (dialogue) ou asset (passif).sco / asset
hrefLa page de lancement (point d’entrée). Requis pour un SCO.phishing/index.html

Et deux enfants :

  • <file href="…"/> : un par fichier que la ressource utilise. Le HTML de lancement, chaque JS, chaque CSS, chaque image locale… tout doit y figurer.
  • <dependency identifierref="…"/> : « cette ressource utilise aussi tous les fichiers de telle autre ressource » — le mécanisme de partage.
<resource identifier="RES_PHISHING" type="webcontent" adlcp:scormType="sco" href="phishing/index.html"> <file href="phishing/index.html"/> <file href="phishing/phishing.js"/> <file href="phishing/quiz.js"/> <dependency identifierref="RES_COMMON"/> </resource>

href vs <file> : pourquoi les deux ?

Question fréquente : si href désigne déjà la page de lancement, pourquoi la re-déclarer en <file> ? Parce qu’ils ne disent pas la même chose :

  • href = « par où on entre » : le fichier que le LMS ouvre quand on lance le SCO. Il y en a un seul par ressource lançable.
  • <file> = « ce dont le paquet est fait » : l’inventaire exhaustif. Il sert au LMS pour savoir quels fichiers extraire/servir, et aux outils de validation pour vérifier que tout est là.

Conséquence pratique : la page de lancement apparaît deux fois — une fois en href, une fois en <file>. C’est normal et voulu.

⚠️ Piège — Oublier de lister un fichier en <file>. Le contenu peut « marcher chez toi » parce que ton serveur local sert tout le dossier ; mais un LMS strict (ou un outil de vérification) ne se fie qu’à l’inventaire <file>. Un phishing.js référencé dans le HTML mais absent de <file> peut être ignoré à l’extraction → écran cassé, script manquant. Règle : tout fichier utilisé par la ressource = un <file>.

💡 Réflexe — Génère la liste des <file> depuis le système de fichiers, pas de mémoire : parcours le dossier de la ressource et déclare chaque fichier réellement présent. Un <file> de trop (fichier listé mais absent) est aussi un défaut : certains validateurs le signalent comme « fichier manquant ».

Les dépendances : factoriser le partagé

Tes trois SCO utilisent tous le même scorm-api.js et la même styles.css. Deux mauvaises voies : dupliquer les fichiers dans chaque dossier (paquet lourd, maintenance pénible), ou re-lister les mêmes <file> dans chaque <resource> (verbeux, source d’oublis). La bonne voie : une ressource commune + des dépendances.

<resources> <!-- SCO 1 : dépend de la ressource commune --> <resource identifier="RES_INTRO" type="webcontent" adlcp:scormType="sco" href="intro/index.html"> <file href="intro/index.html"/> <dependency identifierref="RES_COMMON"/> </resource> <!-- SCO 2 : même dépendance --> <resource identifier="RES_PHISHING" type="webcontent" adlcp:scormType="sco" href="phishing/index.html"> <file href="phishing/index.html"/> <file href="phishing/phishing.js"/> <dependency identifierref="RES_COMMON"/> </resource> <!-- Ressource commune : PAS de href (jamais lancée seule), scormType asset --> <resource identifier="RES_COMMON" type="webcontent" adlcp:scormType="asset"> <file href="shared/scorm-api.js"/> <file href="shared/styles.css"/> <file href="shared/logo.png"/> </resource> </resources>

Points clés :

  • La ressource commune n’a pas de href : elle n’est jamais lancée seule, elle ne fait que fournir des fichiers. Elle est déclarée scormType="asset".
  • <dependency identifierref="RES_COMMON"/> dit au LMS : « pour ce SCO, sers aussi les fichiers de RES_COMMON ». Le paquet ne contient qu’une copie de scorm-api.js.
  • Une ressource peut avoir plusieurs <dependency>. Les dépendances ne s’imbriquent pas de façon récursive fiable selon les LMS : garde-les à un niveau (une ressource commune référencée directement par chaque SCO).

🧭 Sur FormaCampus — FormaCampus factorise systématiquement dans une ressource RES_COMMON : le wrapper scorm-api.js, la CSS de marque et le logo. Gain concret : quand le wrapper est corrigé (par exemple pour mieux « trouver l’API » dans une frame imbriquée), un seul fichier change pour tous les SCO, et le .zip reste léger. C’est aussi ce qui rend le module cohérent visuellement d’un écran à l’autre.

Les chemins : relatifs, sensibles à la casse et aux slashs

Tous les href (de <resource> et de <file>) sont relatifs à la racine du .zip. Trois règles non négociables :

  1. Relatifs, jamais absolus. href="phishing/index.html"jamais href="/phishing/index.html", href="C:\...\index.html" ni href="https://moncdn.com/...". Un chemin absolu casse dès que le LMS extrait le paquet dans son propre espace.
  2. Slashs avant (/), jamais anti-slashs (\). Les URL et le packaging web utilisent /. Un href="phishing\index.html" écrit sous Windows casse sur un serveur Linux.
  3. Casse exacte. Index.htmlindex.html. Ça « marche » sur Windows/macOS (systèmes de fichiers souvent insensibles à la casse), puis casse sur le serveur Linux du LMS. C’est le bug fantôme du packaging.

⚠️ Piège — « Ça marchait sur ma machine. » Le classique absolu du SCORM. Tu testes sous Windows, où Media/Logo.PNG et media/logo.png sont le même fichier. Tu livres, le LMS tourne sous Linux (sensible à la casse), et l’image disparaît, le script ne charge pas, le SCO reste blanc. Aligne rigoureusement la casse des href/<file> sur la casse réelle des fichiers, et bannis les majuscules et espaces dans les noms.

💡 Réflexe — Convention de nommage sûre : tout en minuscules, sans espaces ni accents (mots-de-passe/index.html, pas Mots de passe/Index.html), des tirets plutôt que des espaces. Ça élimine d’un coup les problèmes de casse, d’espaces à encoder (%20) et d’accents mal encodés.

Un bloc resources complet

Le module « Sécurité numérique » au complet — trois SCO, un asset PDF, une ressource commune :

<resources> <resource identifier="RES_INTRO" type="webcontent" adlcp:scormType="sco" href="intro/index.html"> <file href="intro/index.html"/> <file href="intro/intro.js"/> <dependency identifierref="RES_COMMON"/> </resource> <resource identifier="RES_PHISHING" type="webcontent" adlcp:scormType="sco" href="phishing/index.html"> <file href="phishing/index.html"/> <file href="phishing/phishing.js"/> <file href="media/video-phishing.mp4"/> <dependency identifierref="RES_COMMON"/> </resource> <resource identifier="RES_MDP" type="webcontent" adlcp:scormType="sco" href="mots-de-passe/index.html"> <file href="mots-de-passe/index.html"/> <file href="mots-de-passe/passwords.js"/> <dependency identifierref="RES_COMMON"/> </resource> <!-- Asset : un PDF passif, lançable mais ne dialogue pas --> <resource identifier="RES_CHARTE" type="webcontent" adlcp:scormType="asset" href="docs/charte.pdf"> <file href="docs/charte.pdf"/> </resource> <!-- Ressource commune : fournit les fichiers partagés, pas de href --> <resource identifier="RES_COMMON" type="webcontent" adlcp:scormType="asset"> <file href="shared/scorm-api.js"/> <file href="shared/styles.css"/> <file href="media/logo.png"/> </resource> </resources>

Remarque sur l’asset RES_CHARTE : il a un href (docs/charte.pdf) parce qu’il est lançable depuis le menu (l’apprenant clique, le PDF s’ouvre), mais il reste un asset car il ne dialogue pas. Un asset peut donc avoir un href (s’il est directement ouvert) ou ne pas en avoir (s’il ne sert que de réservoir de fichiers, comme RES_COMMON). Ce qui fait le SCO, ce n’est pas le href : c’est le scormType="sco" et le fait qu’il embarque le code de dialogue.

📚 La specadlcp:scormType et le mécanisme <file>/<dependency> sont définis par le Content Packaging du CAM (base 1EdTech) enrichi par ADL. Une <resource> sans href est parfaitement légale : c’est le cas d’usage typique de la ressource « bibliothèque de fichiers » référencée en dépendance. Détails et grammaire exacte : livre CAM, adlnet.gov.

🔌 Côté intégration — À l’import, un LMS rigoureux recoupe l’inventaire <file> avec le contenu réel du .zip. Fichier déclaré mais absent → avertissement ou rejet. Fichier présent mais non déclaré → parfois non servi. Les outils de validation (chapitre 3.5) font exactement ce recoupement. Livrer un paquet dont l’inventaire correspond exactement aux fichiers, c’est passer la validation du premier coup — et éviter le « votre module affiche une page blanche » deux jours après livraison.

✏️ Exercices

Exercice 1 — Compléter l’inventaire. Ce SCO charge dans son HTML : game.js, styles.css (locale) et une image bg.jpg. Complète les <file> manquants.

<resource identifier="RES_GAME" type="webcontent" adlcp:scormType="sco" href="game/index.html"> <file href="game/index.html"/> </resource>

✅ Solution

<resource identifier="RES_GAME" type="webcontent" adlcp:scormType="sco" href="game/index.html"> <file href="game/index.html"/> <file href="game/game.js"/> <file href="game/styles.css"/> <file href="game/bg.jpg"/> </resource>

Chaque fichier réellement utilisé par la ressource doit apparaître en <file>, avec son chemin relatif exact. (Si scorm-api.js était partagé, on ajouterait <dependency identifierref="RES_COMMON"/> plutôt que de le lister ici.)

Exercice 2 — Factoriser. Deux SCO (RES_A, href="a/index.html" ; RES_B, href="b/index.html") utilisent tous deux shared/scorm-api.js et shared/styles.css. Réécris <resources> en factorisant le partagé avec une dépendance.

✅ Solution

<resources> <resource identifier="RES_A" type="webcontent" adlcp:scormType="sco" href="a/index.html"> <file href="a/index.html"/> <dependency identifierref="RES_COMMON"/> </resource> <resource identifier="RES_B" type="webcontent" adlcp:scormType="sco" href="b/index.html"> <file href="b/index.html"/> <dependency identifierref="RES_COMMON"/> </resource> <resource identifier="RES_COMMON" type="webcontent" adlcp:scormType="asset"> <file href="shared/scorm-api.js"/> <file href="shared/styles.css"/> </resource> </resources>

RES_COMMON n’a pas de href (jamais lancée seule), les deux SCO la référencent via <dependency>, et les fichiers partagés ne sont présents qu’une fois dans le .zip.

Exercice 3 — Chasse au bug de chemin. Le SCO fonctionne en local (Windows) mais reste blanc sur le Moodle du client (Linux). Le HTML charge <script src="app.js"> et <img src="Media/Logo.png">, et le dossier réel contient app.js et media/logo.png. Que corriges-tu ?

✅ Solution

Deux problèmes de casse/chemin invisibles sous Windows, fatals sous Linux :

  1. Media/Logo.png (dans le HTML) ≠ media/logo.png (fichier réel) : le serveur Linux est sensible à la casse et ne trouve pas l’image. Corriger la référence en media/logo.png (et aligner le <file> du manifeste).
  2. Vérifier que tous les fichiers (app.js, media/logo.png) sont bien déclarés en <file> avec la casse exacte et des slashs avant.

Bonne pratique de fond : passer tous les noms en minuscules sans espaces/accents, pour supprimer la classe entière de ces bugs.

🧠 Quiz de révision

1. Que déclare le bloc resources ?

L’inventaire des fichiers du paquet, groupés par <resource>. Chaque ressource porte un identifier, un type (webcontent), un adlcp:scormType (sco/asset), éventuellement un href de lancement, et la liste de ses <file>.

2. Quelle est la différence entre href et un file ?

href désigne la page de lancement (le point d’entrée, un seul par ressource lançable). <file> déclare chaque fichier de la ressource (inventaire exhaustif). La page de lancement figure donc à la fois en href et en <file> — c’est normal.

3. À quoi sert dependency ?

À partager des fichiers entre ressources sans les dupliquer. Une ressource « commune » (souvent sans href) liste les fichiers partagés, et chaque SCO la référence via <dependency identifierref="RES_COMMON"/>. Le .zip ne contient alors qu’une seule copie des fichiers communs.

4. Pourquoi un chemin peut-il marcher en local et casser sur le LMS ?

À cause de la casse (et des slashs). Windows/macOS sont souvent insensibles à la casse ; le serveur Linux du LMS, lui, l’est. Media/Logo.PNGmedia/logo.png : le fichier « disparaît » côté serveur. Règle : casse exacte, slashs avant, idéalement tout en minuscules sans espaces ni accents.

5. Une resource peut-elle exister sans href ? Dans quel cas ?

Oui. Une ressource sans href n’est jamais lancée seule : elle sert de réservoir de fichiers (typiquement la ressource commune référencée en <dependency>). On la déclare généralement en scormType="asset".


Chapitre suivant : Empaqueter & valider — on assemble tout : construire le PIF à la main, éviter les erreurs classiques, et tester le paquet avant de le livrer.

Last updated on