Utilisation de l'infrastructure de développement web

Portail informatique

Création d'un cours complet

L'infrastructure repose sur un système d'aiguilleur. L'aiguilleur est le point d'entrée d'un cours et toute les requêtes webs passent par cet aiguilleur. En tant que concepteur de cours, il faut définir quelques variables dans cet aiguilleur puis l'aiguilleur délègue l'affichage à l'infrastructure. L'infrastructure, elle, s'occupe de la mise en page et d'afficher une page, appelée page courante passée en argument de l'aiguilleur.

Typiquement, si on suppose que l'aiguilleur s'appelle index.php, une requête s'écrit de la façon suivante : http://server/chemin/index.php?page=une-page. L'aiguilleur affichera alors le contenu de une-page.php après le bandeau en haut. Notez qu'il ne faut pas mettre l'extension .php dans l'URL.

Pour utiliser l'infrastructure, vous devez définir trois fichiers php au minimum :

  • Un aiguilleur. Ce fichier contient donc la définition de quelques variables et délègue la gestion du cours à un fichier fourni par l'infrastructure de cours.
  • Un fichier de navigation contenant le menu de navigation du module, agrémenté de quelques marqueurs pour générer le plan général du module ou l'ensemble des supports de TPs.
  • Une page par défaut. Cette page est affichée par défaut si le paramètre page n'est pas renseigné. Lorsqu'on clique sur le titre du cours, on arrive aussi sur cette page.

L'aiguilleur

L'aiguilleur se présente sous la forme suivante :

<?php

$root 
dirname(__FILE__);       /* root directory of the module */
$web '../infra-web-cours';     /* relative path of the web infrastructure (the infrastructure is in $root . '/' $web) */

$language 'fr';                /* pour avoir les termes en anglais, il faut utiliser en */
$moduleId 'CSC0000';           /* id of the module, used to generate the calendar */
$module "Utilisation de l'infrastructure de développement web";  /* name of the module */

//$myCss = 'cours.css';            /* css of the module (optional) */

$planning 'planning-2019.php'/* calendar of the module, see the associated help section */

$nav 'nav';                    /* nav file (technically, nav is in $root . '/' . $nav . '.php') */
$main 'example';               /* main file (technically, main is in $root . '/' . $main . '.php') */

include($root '/' $web '/tsp.php');
?>

<!-- Local Variables: -->
<!-- mode: web -->
<!-- indent-tabs-mode: nil -->
<!-- mode: flyspell -->
<!-- ispell-local-dictionary: "french" -->
<!-- coding: utf-8 -->
<!-- End: -->

Les principales variables sont :

  • $root contient le répertoire dans lequel se trouve l'aiguilleur. Il ne devrait jamais être nécessaire de modifier cette ligne.
  • $web indique où se trouve la partie web relativement à root. Dans notre cas, la partie web se trouve en '../infra-web-cours'.
  • $module donne le nom du module. Cette information est nécessaire pour créer le bandeau en haut de la page et pour générer le titre de la page.
  • $planning donne le planning de l'année en cours (voir l'aide ici).
  • Finalement, la variable $nav indique le fichier de navigation du module sans l'extension '.php' (voir après) et la variable $main la page par défaut du module sans l'extension '.php' (dans notre cas la page example).

Le fichier de navigation

Le fichier de navigation sert d'abord à générer les menus. Le fichier de navigation utilisé dans cette aide est donné ici :

<!-- n'affiche que les min-week <= 2 -->
  <ul class='current-week' data-current-week='2'>             <!-- ul est un marqueur de menu ou sous menu -->
    <li>           <!-- et un li indique une entrée d'un menu -->
      Organisation
      <ul>
        <li><?php echo "<a href='?page=" $main "'>Page principale</a>"?></li>
        <li><a href='?page=planning'>Planning</a></li>
        <li><a href='?page=all'>Tous les sujets de TP</a></li>
        <li class='min-week' data-min-week='2'>On est en semaine 2&nbsp;!</li>
        <li class='min-week' data-min-week='3'>Ceci ne s'affichera que quand data-current-week vaudra 3</li>
      </ul>
    </li>

    <li>
      Supports
      <ul class='chapitres'> <!-- le marqueur chapitres est utilisé pour générer le séquencement -->

        <li>                 <!-- chaque li définit un chapitre -->
          <chapter-id>C1</chapter-id>
          <chapter-title>Installation</chapter-title> <!-- utilisé à la fois dans le menu est dans le séquencement -->
          <chapter-content>
            <ul> <!-- le ul ici est important, c'est ce qui indique que c'est un sous-menu du chapitre -->
              <li><a class='all-in-one' href='?page=installation'>Cours</a></li>
            </ul>
          </chapter-content>
          <chapter-notion>
            <ul> <!-- le ul ici n'est pas important, cette zone n'est affichée que dans le séquencement -->
              <li>Test avec PhP</li>
              <li>Installation complète avec Apache</li>
            </ul>
          </chapter-notion>
        </li>

        <li>
          <chapter-id>C2</chapter-id>
          <chapter-short>Création d'un cours</chapter-short><!-- si chapter-short présent, utilisé dans les menus -->
          <chapter-title>Création d'un cours complet</chapter-title><!-- et le long ailleurs -->
          <chapter-content>
            <ul>
              <li><a class='all-in-one' href='?page=creation'>Cours</a></li>
            </ul>
          </chapter-content>
          <chapter-notion>
            <ul>
              <li>Création d'un cours complet</li>
              <li>Fonctionnement de l'aiguilleur</li>
            </ul>
          </chapter-notion>
        </li>

        <li>
          <chapter-id>C3</chapter-id>
          <chapter-title>Les balises</chapter-title>
          <chapter-content>
            <ul>
              <li><a class='all-in-one' href='?page=balises'>Cours</a></li>
              <li><a class='all-in-one' href='?page=new'>Un petit exemple</a></li>
            </ul>
          </chapter-content>
          <chapter-notion>
            <ul>
              <li>Liste de toutes les balises</li>
            </ul>
          </chapter-notion>
        </li>


        <li>
          <chapter-id>C4</chapter-id>
          <chapter-title>Gérer des planning</chapter-title>
          <chapter-content>
            <ul>
              <li><a class='all-in-one' href='?page=edt'>Cours</a></li>
            </ul>
          </chapter-content>
          <chapter-notion>
            <ul>
              <li>Générer et afficher des plannings</li>
            </ul>
          </chapter-notion>
        </li>

        <li>
          <chapter-id>C5</chapter-id>
          <chapter-title>Informations diverses</chapter-title>
          <chapter-content>
            <ul>
              <li><a class='all-in-one' href='?page=divers'>Cours</a></li>
            </ul>
          </chapter-content>
          <chapter-notion>
            <ul>
              <li>Gestion des chemins dans les cours</li>
              <li>Configuration avancée de l'affichage</li>
            </ul>
          </chapter-notion>
        </li>


        <!-- quelques exemples un peu plus avancés -->
        <li> 
          <chapter-id>
            <expanded-version><img src='alarm.png' width="14px"></img></expanded-version> <!-- ignoré dans le menu -->
            A1
          </chapter-id>

          <!-- si chapter-short présent, utilisé dans les menus -->
          <chapter-short>Exemple avancé</chapter-short>
          <!-- le titre long est utilisé ailleurs -->
          <chapter-title>Exemple avancé avec un titre mega long car j'aime bien les titres longs</chapter-title> 

          <chapter-content>
            <ul>
              <li>
                <a href='#'>Le cours (pas de lien, c'est normal)</a>
                <expanded-version> &ndash; 20mn</expanded-version> <!-- ignoré dans le menu -->
              </li>
              <li>
                <a href='#'>TP (pas de lien, c'est normal)</a>
                <expanded-version> &ndash; 15mn + 1h25</expanded-version>
              </li>

              <li ignore>Ma partie du cours que je ne veux pas rendre visible</li>
            </ul>
          </chapter-content>
          <chapter-notion>
            Le format de la case notion est totalement libre.
          </chapter-notion>
        </li>

        <li only-schedule> <!-- ce chapitre n'est affiché que dans le tableau de séquencement -->
          <!-- on peut utilise only-nav pour n'afficher un chapitre que dans le menu (comportement inverse) -->
          <chapter-id>
            CI42
          </chapter-id>
          <chapter-title>Chapitre qui n'apparaît que dans schedule et pas dans le menu</chapter-title>
          <chapter-content>
            <ul>
              <li>
                <a href='#'>Une ressource</a>
                <expanded-version> &ndash; 20mn</expanded-version> <!-- ignoré dans le menu -->
              </li>
            </ul>
          </chapter-content>
          <chapter-notion>
            L'attribut schedule-only
          </chapter-notion>
        </li>
      </ul>
    </li>
  </ul>
</week>

<!-- Local Variables: -->
<!-- mode: web -->
<!-- indent-tabs-mode: nil -->
<!-- mode: flyspell -->
<!-- ispell-local-dictionary: "french" -->
<!-- coding: utf-8 -->
<!-- End: -->

Les menus et sous-menus sont donnés par les listes (<ul> et <li>). Outre le fait qu'elle est affichée en tant que menu, la liste <ul> avec la classe chapitres a aussi un rôle particulier. Chaque élément de cette liste définit un chapitre (une séance). Ces chapitres permettent de :

  • Générer le page contenant tous les TPs an agrégeant tous les contenus associés aux balises <a> ayant la classe all-in-one dans le fichier de navigation. Vous pouvez voir le résultat de cette agréagation ici. Le code de cette page qui agrège l'ensemble des sujets est assez simple :
    <all-in-one></all-in-one>
  • Générer un tableau contenant le séquencement pédagogique du module (voir la suite).

Par défaut, un chapitre est donc affiché à la fois en tant que sous-menu et dans la page de séquencement. On peut changer ce comportement avec deux attributs qu'on peut adjoindre à une balise <li> :

  • L'attribut ignore indique que le chapitre <li> doit être totalement ignoré, comme dans :
    <li ignore>Ma partie du cours que je ne veux pas rendre visible</li>
    Cet attribut permet de masquer certaines parties du cours si on souhaite ne les rendre visibles qu'au fur et à mesure de la progression du cours.
  • L'attribut only-schedule permet d'indiquer que le chapitre doit apparaître dans la page schedule, mais pas dans les menus, ce qui permet d'alléger les menus, ou de traiter différemment des chapitres à faire en hors présentiel.
  • L'attribut only-nav a le comportement inverse, le chapitre ne sera affiché que dans le menu.

On peut aussi facilement gérer l'affichage de certains éléments en jouant avec les classes current-week et min-week. Le fichier de navigation donné en exemple illustre le fonctionnement : seules les balises avec une classe min-week avec un attribut data-min-week supérieur à 2 (c'est-à-dire supérieur à l'attribut data-current-week de la balise avec la classe current-week) sont affichées.

Pour illustrer, voici le séquencement pédagogique associé au fichier de navigation donné en exemple :

  • Sujets
    Supports
    Notions clés
  • C1
    Installation
    • Test avec PhP
    • Installation complète avec Apache
  • C2
    Création d'un cours
    Création d'un cours complet
    • Création d'un cours complet
    • Fonctionnement de l'aiguilleur
  • C3
    Les balises
    • Liste de toutes les balises
  • C4
    Gérer des planning
    • Générer et afficher des plannings
  • C5
    Informations diverses
    • Gestion des chemins dans les cours
    • Configuration avancée de l'affichage
  • A1
    Exemple avancé
    Exemple avancé avec un titre mega long car j'aime bien les titres longs
    Le format de la case notion est totalement libre.
  • CI42
    Chapitre qui n'apparaît que dans schedule et pas dans le menu
    L'attribut schedule-only

Le code permettant de générer ce séquencement est le suivant :

<schedule>
  <li>
    <chapter-head></chapter-head>
    <chapter-head>Sujets</chapter-head>
    <chapter-head>Supports</chapter-head>
    <chapter-head>Notions clés</chapter-head>
  </li>
  <generate-schedule></generate-schedule>
</schedule>

Les balises chapitre-* servent à générer le séquencement et les menus. Les informations données dans chapitre-id et chapitre-title servent à générer le menu de premier niveau dans Supports et la liste donnée dans la balise chapitre-content le menu de deuxième niveau.

Vous avez enfin deux balises optionnelles qui vous sont proposées pour les parties séquencements :

  • Si vous voulez un titre court dans le menu et un titre long dans le séquencement, il suffit d'ajouter une balise chapter-short comme dans l'exemple.
  • Si vous voulez afficher des informations complémentaires dans le séquencement mais pas dans le menu de navigation, vous pouvez utiliser la balise expanded-version comme dans l'exemple.

Les options de l'aiguilleur

L'aiguilleur prend jusqu'à trois arguments :

  • page=fichier : indique le fichier qu'on souhaite afficher à l'intérieur de l'aiguilleur. Le chemin du fichier est relatif au répertoire racine ($root) et le suffixe .php est implicite. Si ce paramètre est omis, il prend la valeur $main
  • soluce=[true|false] : indique si on souhaite afficher la solution. Si ce paramètre est omis, soluce vaut false
  • wrap=[true|false] : indique si on souhaite afficher les solutions déjà déroulées ou si on souhaite n'afficher qu'un bouton permettant d'afficher les solutions. J'ai fait un chouette contre-sens quand j'ai conçu l'infrastructure, wrap à vrai indique qu'un menu est déroulé :). Pour une présentation d'une solution aux étudiants, on préférera laisser ce paramètre à false, alors que pour imprimer un corrigé, on préférera passer ce paramètre à true. Si ce paramètre est omis, il vaut false par défaut.
  • preprint=[true|false] : déroule automatiquement les balises details et tip, ce qui est utile pour l'impression d'un fascicule.

Pour une utilisation de tous les jours :

  • &page=ma-page : pour les étudiants quand ils surfent (pas de corrigé, détails/tip pas déroules),
  • &page=ma-page&soluce=true : pour les enseignants en version vidéo-projeté quand on veut pouvoir faire apparaître les détails, tips et solutions au fur et à mesure (bouton solution, solutions/details/tip pas déroulés),
  • &page=ma-page&preprint=true : fascicule de l'étudiant à imprimer (pas de corrigé, détails/tip déroulés),
  • &page=ma-page&preprint=true&soluce=true&wrap=true : fascicule de l'enseignant à imprimer (corrigés, détails et tips sont tous déroulés).

Arborescence du projet

Ca chapitre décrit comme extraire certains répertoires du projet afin d'embarquer votre propre copie de infra-web-cours à l'intérieur de votre cours. Si vous reposez sur la version installée sur www-inf.telecom-sudparis.eu/cours ou si vous conservez l'arborescence du projet inchangée, vous n'avez pas besoin des explications qui suivent.

La variable wppath

Le projet infra-web-cours est constitué de deux sous-parties. La première, appelée sous-partie wordpress, est utilisée à la fois par l'infrastructure pour les cours, mais aussi par le wordpress du département de façon à unifier la présentation des sites webs des équipes avec celles des pages de cours. La seconde, appelée sous-partie cours, ajoute des spécificités pour gérer les cours (typiquement la balise <schedule>).

Si on suppose que le chemin vers la racine du projet infra-web-cours est défini dans la variable INFRA_WEB_COURS, alors $INFRA_WEB_COURS/wp contient la sous-partie wordpress et $INFRA_WEB_COURS/infra-web-cours contient la sous-partie cours. Comme la sous-partie cours repose sur la sous-partie wordpress, la sous-partie cours trouve le chemin vers la sous-partie wordpress dans la variable wppath. Par défaut, cette variable pointe vers la sous-partie wordpress se trouvant dans le projet, ce qui devrait correspondre à 99% des cas d'utilisations. Toutefois, si par hasard vous avez besoin de stocker la sous-partie wordpress dans un répertoire différent, il faut alors modifier wppath. Pour cela, il suffit de copier le fichier config.sample.php se trouvant dans le répartoire $INFRA_WEB_COURS/infra-web-cours/current en config.php dans le même répertoire et d'ajuster la variable wppath en fonction de votre abroescence.