ZEP-12 : refonte du principe des tutoriels et articles

Avec pour base atomique ... l'extrait

Le problème exposé dans ce sujet a été résolu.

NOTE: Cette ZEP possède une spécification technique, située ici.

Cartouche
ZEP 12
Titre refonte du principe des tutoriels et articles
Révision 8
Date de création 25 juillet 2014
Dernière révision 16 septembre 2014
Type Feature
Statut En production

Cette ZEP-12 a pour but de donner les spécifications pour améliorer fortement le système d'édition de tuto zds. Pour obtenir l'état de ce qu'il se fait dans le module de tuto lors de la rédaction de la ZEP, c'est ici. Pour les discutions concernant le système de versionnage des tutoriels, c'est dans la ZEP-08.

Situation générale

Aujourd'hui, les tutoriels et articles sont considérés comme des entités séparées. Un article repose sur un seul extrait1. Concernant les tutoriels, on retrouve les mini-tutoriels, qui sont composés d'un chapitre comprenant plusieurs extrait et les big-tutoriels qui sont composés de plusieurs parties, comprenant plusieurs chapitres, comprenant plusieurs extraits.

Durant une discutions sur la possibilité de tutoriaux de longeurs intermédiaires, feature manquante à ZdS et qui semblait retenir l'attention de la communauté, ShigeruM a proposé que pour casser les barrières entre les différents niveaux de structures des tutoriaux (mini/moyen/big), on repense le système afin de mettre comme base base atomique "l'extrait". Cette ZEP reprend fortement cette idée.

L'extrait, base atomique

Dans cette nouvelle vision des choses, il faudrait que l'utilisateur puisse rédiger et assembler les extraits "comme bon lui semble" sur 4 niveaux de structures, qui définiraient ce qu'est le tutoriel/l'article :

  • Extrait seul : il s'agit d'un article
  • Plusieurs extrait rassemblés sous un même titre (chapitre ?) : il s'agit d'un mini-tuto
  • Plusieurs chapitre rassemblé sous un même titre (partie ?) : il s'agit d'un moyen-tuto
  • Plusieurs parties rassemblées sous un même titre : il s'agit d'un big-tuto

Mise en place

Il sera nécessaire d'écrire un script de migration si cette ZEP voit le jour.

Généralité :

Un document sera construit grâce à trois objets :

1
2
3
4
5
6
Document (conteneur principal, conservé en base de donnée avec les métadonnées)
  |
  +-- Section (conteneur secondaire, avec titre, introduction et conclusion et 
      peuvent s’emboîter dans eux-même jusqu'à 3 niveaux)
         |
         +-- Extrait (conteneur tertiaire correspondant à un fichier de contenu et à un titre)

ou, de manière plus complète, comme suis :

Diagramme de classe à implémenter

  • Un Document aura pour enfant une Section, qui détermineront le titre du tutoriel, et son éventuelle introduction/conclusion
  • Une Section aura pour parent soit une autre Section, soit un Document et pour enfant une liste de Sections ou une liste d'Extrait.
  • Un Extrait représentera un fichier Markdown et possédera un titre.
  • La liste des métadonnées associées à un tutoriel est reprise ici

La structure doit permettre une liberté dans la construction du Document, un extrait ne devant pas forcément avoir pour parent 3 Sections. Ce genre de structure doit être permises, en fonction des souhaits de l'auteur :

 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
Document
    |
    +--- Section
    |       |
    |       +--- Extrait : blabla
    |       +--- Extrait : blabla
    |       +--- Extrait : blabla
    |
    +--- Section
    |       |
    |       +--- Extrait : blabla
    |
    +--- Section
    |       |
    |       +--- Section
    |       |       |
    |       |       +--- Extrait : blabla
    |       |       +--- Extrait : blabla
    |       |       +--- Extrait : blabla
    |       |
    |       +--- Section
    |               |
    |               +--- Extrait : blabla
    |               +--- Extrait : blabla
    |               +--- Extrait : blabla
    |
    +--- Section
            |
            +--- Extrait : blabla
            +--- Extrait : blabla
            +--- Extrait : blabla

Cette structure sera écrite de manière complète dans le manifest.json, et c'est ce même fichier qui permettra la construction de la structure du document, qui ne doit donc pas être stockée en base de donnée. Ce manifest.json aura une structure qui reprendra le diagramme de classe repris ci-dessus.

En fonction de cette structure, les fichiers correspondants seront déplacés dans des dossiers.

L'auteur devra pouvoir déplacer un extrait dans n'importe quelle section du document.

Chaque Section et chaque Extrait doit présenter une clé nominale unique permettant de les différencier (et d'éviter les doublons) et de les retrouver facilement dans la structure du Document.

Visualisation :

  • En fonction de la "profondeur" du "Document", le front adoptera la bonne manière de présenter les choses. Une seule template sera nécessaire à la visualisation de chaque niveau; puisqu'il ne s'agit que de visualiser un conteneur donné.
  • La distinction article/tutoriel (nécessaire à la page d'accueil) se fera sur le "Document" au moment de l'exportation, sur base de la structure interne. À ce moment, s'il s'agit d'un article, il faudra que la structure soit gelée (pour qu'un article ne devienne pas un tutoriel par la suite).
  • L'exportation qui est faite à la publication devrai générer un fichier HTML qui minimise au maximum la re-construction à postériori. Typiquement, il faut qu'une Section de Sections possède également un fichier HTML avec son introduction, sa conclusion et des liens vers les Conteneur enfants, et ce pour minimiser la lecture disque ainsi que le travail a effectuer par le back lors de la visualisation d'un tutoriel.

Édition :

  • La méthode actuelle est conservée, la modification de la Section (ainsi que son déplacement éventuel), ce fait sur la page de ce dernier.
  • Les extraits doivent pouvoir être modifié sur une page à part, comme c'est le cas aujourd'hui.
  • Il est nécessaire de limiter les libertés de l'auteur afin qu'il ne puisse pas placer plus de deux extraits dans une Section de Sections ou placer une Section enfant dans une Section contenant déjà des Extraits

Proposition d'UI s'adaptant en fonction du cas


Section vierge

Ajouter une introduction

Ajouter un extrait

Ajouter une section

Ajouter une conclusion


Section ayant déjà des extraits

Ajouter une introduction

  • Extrait 1
  • Extrait 2

Ajouter un extrait

Ajouter une conclusion


Section ayant déjà des sections enfants

Ajouter une introduction

  • Section existante

Ajouter une section

Ajouter une conclusion


Conteneur ayant déjà un conteneur et un extrait en guise d'intro

  • Extrait "Introduction"

  • Section existante

Ajouter une section

Ajouter une conclusion


Conteneur ayant déjà un conteneur et un extrait en guise d'intro et un second en guise de conclusion

  • Extrait "Introduction"

  • Section existante

Ajouter une section

  • Extrait "Conclusion"

Non-régression

L'implémentation de cette ZEP devra se faire en tenant particulièrement compte des points suivants :

  • Le contenu actuel du site (article, tutoriel, etc.) doit pouvoir être migrés vers le nouveau système sans perte d'historique des fichiers, ni d'url.
  • On ne doit pas avoir de régression du système par rapport à l'existant, c'est à dire :
    • On doit pouvoir créer deux extrait avec le même nom
    • Les urls existantes doivent rester valides (SEO toussa)
    • On doit pouvoir importer les fichiers .tuto et archives zip
    • On doit pouvoir générer les exports (epub, pdf, etc) au moins aussi bien que maintenant
    • Les pages d'un tuto et articles doivent s'afficher en moins d'une seconde
    • La recherche dans les contenu doit rester stable
    • Le sommaire d'un tutoriel doit être disponible sur toutes les pages dans la sidebar
    • La navigation par chapitre doit continuer à fonctionner, peut être différemment, mais garder une navigation par contenu logique.

La ZEP-12 ne change pas le contenu versionné, qui est le rôle de la ZEP-08


  1. un extrait possède pour sens physique un fichier contenant du texte formaté en markdown. 

+6 -0

Je ne suis pas en accord avec tout.
Oui l'extrait est le composant "atomique".
Mais je trouve très clairement qu'introduire "partie, chapitre…" c'est juste finalement nier cela.

Je vois plus une organisation similaire à ce qu'on peut trouver dans les UI (WinForm/Swing) : Deux types de composants : les extraits et les conteneurs.

un conteneur contient une intro,une conclusion et entre deux un ou plusieurs autres composants (donc extraits ou conteneur). Et encore, intro et conclusion ne devrait pas être nécessaires !

Pourquoi faire cela?

J'écris un "big tuto" selon la convention actuelle. J'ai une "partie" qui s'appelle "astuces et points particuliers", aka "bon je savais pas où en parler mais si j'en parlais pas le tuto n'aurait aucune valeur".

En vérité, chaque chapitre est en soit important, mais comme on est "templaté" big tuto, je suis obligé de les encapsuler dans une partie. Et comme une partie avec un seul chapitre c'est déstabilisant pour les gens bah on est obligé de rassembler les choses.

Etrangement, déployer un site ASP.NET c'est quand même ultra important et devrait donc mériter d'être de premier niveau dans la hiérarchie. Mais comme déployer un site ASP.NET c'est qu'un chapitre, bah il doit être dans une partie et donc perdre un niveau de hiérarchie.

Si notre but c'est d'avoir un sens et d'être accessibles, il faut réagir en terme de hiérarchie du contenu. Et proposer une souplesse côté technique mais un templating fermé et embêtant côté rédaction et affichage c'est juste contradictoire.

Je plussoie l'idée de favoriser la hiérarchisation intelligente à la structure. Le problème réside alors dans la manière de présenter ça au lecteur en restant lisible et ergonomique (et pas trop déstabilisant). Avec tes chapitres qui se baladeraient à la fin de ton tuto, je vois difficilement comment organiser le sommaire et le rendre compréhensible, même si c'est effectivement plus logique en termes d'organisation (logique != confort de rendu).

+0 -0

Peut-être une precision sur ce que devient l'introduction et la conclusion des chapitres/parties/tutoriel ?

firm1

Sous la forme actuelle, on sait qu'ils sont là. je veux dire par là que forcément, un tuto a une intro/conclu, une partie pareil, un chapitre pareil, … Soit on considère de manière implicite leur présence, ou à la limite, on en fait des extraits à part entière. Ceci dit, je suis un peu partagé sur la question, perso, c'est un de mes gros points d'interrogation.

assez simplement je pense :

  • tu autorises une profondeur maximale de 4
  • tu organises ton sommaire comme le fait latex : tu utilises les niveaux hiérarchiques.

artragis

En gros, pour que je te suive bien … Actuelement, tu as ça :

tuto (niveau 1)

Partie 1 (niveau 2)

Chapitre 1 (niveau 3)

Liste d'extrait

Chapitre 2 (niveau 3)

Liste d'extrait

Partie inutile (niveau 2)

Chapitre important (niveau 3)

Liste d'extrait

Et tu voudrait

tuto

Partie 1 (niveau 2)

Chapitre 1 (niveau 3)

Liste d'extrait

Chapitre 2 (niveau 3)

Liste d'extrait

Chapitre important (niveau 2)

Liste d'extrait

J'ai envie de dire, pourquoi pas. Ceci étant, dans une navigation linéaire comme on l'as actuellement (on passe de chapitre en chapitre), cette mise en évidence dans le plan se traduira par rien du tout, si ? Parce que un titre plus gros ou pas, l'utilisateur s'en fout un peu, surtout si on met à plat les niveaux de titre pour que ça reste cohérent (genre, dans un tuto/article, un niveau de titre 1 en markdown équivaut à un titre 3, <h3>, et ainsi de suite). Donc cette mise en évidence dans le plan est … Plus dure à traduire à l'écran.

+2 -0

. Ceci étant, dans une navigation linéaire comme on l'as actuellement (on passe de chapitre en chapitre), cette mise en évidence dans le plan se traduira par rien du tout, si ?

En navigation linéaire, non. En navigation par le sommaire, ça se traduit par un accès plus rapide à ce qui est important.

Je vois. Et donc … Si on fait la chose suivante, est ce que ça passe ?

1
2
3
4
5
6
Document (conteneur principal, avec entre autre les sha pour git, description, image, ...)
  |
  +-- Sous-document (conteneur secondaire, avec titre, intro et conclu et peuvent s’emboîter 
      dans eux-même jusqu'à 4 niveaux)
         |
         +-- Extrait (conteneur tertiaire avec titre et fichier de contenu)

À chaque fois, un "sous-document"1 possède un "sous-document" parent et une liste de "sous-documents" enfants ou une liste d'extraits enfants. Un "Document" ne possède qu'un sous-document pour enfant, qui donnerait dès facto le titre du tutoriel et son intro/conclusion.

Comme ça, on pourrait imbriquer un certain nombre de conteneur secondaires pour arriver au niveau de structure souhaité et seul le "Document" serait conservé en base comme "point d'appui" pour tout le reste (et pour garder les empreintes des différentes version/branches/whatever).


  1. ou une "Section", pour se rapprocher du LaTeX. 

+2 -0

+100 pour les extraits/composants

Je rajouterais qu'une intro et une conclusion doivent être des extraits, pour pousser le truc jusqu'au bout. Parfois on ne sait que mettre en conclusion ou encore on a une intro qui ne sert à rien. Autant laisser le libre choix à chaque auteur de mettre ou non une intro et une conclusion.

Ainsi on aurait :

  • Conteneur
    • Extrait : introduction
    • Extrait : blabla
    • Extrait : blabla
    • Extrait : blabla
    • Extrait : conclusion
  • Conteneur
    • Extrait : introduction
    • Extrait : blabla
  • Conteneur
    • Conteneur
      • Extrait : introduction
      • Extrait : blabla
      • Extrait : blabla
      • Extrait : blabla
      • Extrait : blabla
      • Extrait : conclusion

Et franchement, ça me semble encore plus simple à gérer au niveau du modèle, plutôt que d'avoir plein de types de choses différentes.

Ca permet entre autre d'uniformiser l'interface de rédaction (faut aussi penser à l'UI/UX) et d'avoir tous les outils type "Aperçu", "Envoyer" qui ne touche qu'un bloc à la fois, intro et conclusion compris.

On pourrait imaginer des articles composés de plusieurs conteneur pour avoir un nouveau type de contenu : des "dossiers". Et ainsi de suite, libre à chacun de construire ce qu'il veut comme il veut.

Il faut limiter à 3 niveaux (et pas à 4) car après, c'est incompréhensible et très sincèrement, pour avoir fait le sommaire dans la sidebar sur 3 niveaux, c'est déjà pas évident que ce soit clair.

Voilà voilà, pour moi ça doit être atomique et modulable, avec une limite en profondeur. Le tout se basant uniquement sur des fichiers et du git : comme actuellement, mais sans la BDD.

Il faut limiter à 3 niveaux (et pas à 4) car après, c'est incompréhensible et très sincèrement, pour avoir fait le sommaire dans la sidebar sur 3 niveaux, c'est déjà pas évident que ce soit clair.

My bad, je sais plus comment j'ai fait mon compte, mais je crois que je me suis basé sur le fait qu'un article était un niveau, alors que c'est juste un conteneur avec un extrait dedans. Donc de fait, c'est trois.

Voilà voilà, pour moi ça doit être atomique et modulable, avec une limite en profondeur. Le tout se basant uniquement sur des fichiers et du git : comme actuellement, mais sans la BDD.

Pour moi, faut quand même laisser les empreintes git en bdd (pour des raisons qui me semblent évidentes), et un minimum d'info sur l'auteur et le titre (et encore, le titre pas certain, puisqu'il est versionné), pour pas avoir à crawler tout les tutos en cas de recherche (je pense à "mes tutoriels" ou à "tutoriels en bêta/en ligne par <xxx>", par exemple). Ceci dit, comme Firm1 l'as bien dit sur son état de l'art du module des tutoriels, il s'agit bien de limiter les infos qui doivent être stockées en BDD et de s'appuyer un maximum sur git.

EDIT : donc pour moi, cette ZEP demande aussi de réfléchir à ce qui doit aller en base et ce qui doit pas y aller.

+1 -0

Ça dépend du modèle git qui est derrière, du coup c'est plutôt dans l'autre ZEP que ça sera à discuter.

Ce que je veux dire c'est qu'en base, rien du schéma du tuto de doit figurer. Déplacer une extrait ou un conteneur, c'est déplacer des lignes du manifest d'un conteur à un autre.

Faut aussi considérer que par défaut, on a un conteneur global, dans le titre est le titre du tuto. Faut vraiment pousser le concept jusqu'au bout pour être souple au maximum. Certes le conteneur global, il sera accompagné de metadonnées (licence, auteur, etc.) mais tout ce qui peut être mis en commun doit l'être.

Ça dépend du modèle git qui est derrière, du coup c'est plutôt dans l'autre ZEP que ça sera à discuter. Ce que je veux dire c'est qu'en base, rien du schéma du tuto de doit figurer. Déplacer une extrait ou un conteneur, c'est déplacer des lignes du manifest d'un conteur à un autre.

Je vais aller voir de l'autre coté. Ceci dit, je suis d'accord avec ça.

Faut aussi considérer que par défaut, on a un conteneur global, dans le titre est le titre du tuto. Faut vraiment pousser le concept jusqu'au bout pour être souple au maximum. Certes le conteneur global, il sera accompagné de metadonnées (licence, auteur, etc.) mais tout ce qui peut être mis en commun doit l'être.

C'est ce que j'essaye de reproduire avec mon "Document" de quelques posts plus haut. Pour moi, ce serait ce conteneur là auquel sont rattachées les métadonnées et qui serait représentatif des infos en BDD.

Je vais essayer de faire un update demain de la ZEP pour reprendre un peu tout ce qui a été dit.

Donc imaginons. Je crée un document (c'est chiant de pas pouvoir l'appeler "article" ou "tuto", mais c'est comme ça ^^).

  • Dedans, je peux ajouter des Conteneurs (faudra un nom plus vendeur), ou des Extraits. Au moment ou j'ai choisi de rajouter l'un ou l'autre, je peux plus rajouter l'autre. (pas d'Extrait dans un Conteneur qui en contient d'autre, ou on va plus s'en sortir).
  • Si jamais j'ai créé un Extrait, je peux toujours modifier sa place dans le Conteneur, ou le balancer dans un autre Conteneur
  • Si on garde ce principe de "intro/conclusion est un Extrait" (faudrait statuer là dessus), faut pas qu'ils soient déplaçables (à la limite entre Conteneur). Faut pas non plus qu'ils aie de titre, si on s'en tient à ce qui est fait actuellement.
  • Pourrait-on envoyer un conteneur dans un autre, ou est ce que c'est trop tordu ? Sachant qu'il faudrait alors gérer les cas du genre "envoyer un conteneur dans un de ces conteneur enfant" :p

Petite question qui semble épineuse : au vue des profilages actuels il semble que l'affichage des tutoriels passe un temps fou dans le templating.

Je propose que nous ajoutions en bdd une version préparsée du tutoriel dès qu'un tutoriel est publié. Avec une telle version, nous gagnerions énormément de temps puisqu'il ne s'agirait que d'un simple get dans la BDD au lieu de tous les problèmes d'accès disque puis reparsage du json etc.

+1 -0

Je propose que nous ajoutions en bdd une version préparsée du tutoriel dès qu'un tutoriel est publié. Avec une telle version, nous gagnerions énormément de temps puisqu'il ne s'agirait que d'un simple get dans la BDD au lieu de tous les problèmes d'accès disque puis reparsage du json etc.

Lors de la publication d'un tutoriel, tout le markdown est parsé et transformé en HTMl. En gros, y'a plus qu'à aller lire le fichier HTML et l'afficher. Donc ça ou un GET de base de donnée (qui revient aussi à de l'accès disque), ça va être kif, selon moi. Mais évidement, y'a de l'opti' à faire sur tout le système pour limiter au maximum les accès disques (genre éventuellement parser le contenu des pages des conteneurs pour plus avoir à interroger la structure interne qu'en absolue nécessité ??).

Ce qu'il faut optimiser, c'est le nombre de fichiers à lire. Par exemple, lors de la publication, il faut faire un fichier par conteneur et non pas un fichier pour le conteneur + 1 par extrait. Sachant que pour moi un conteneur, c'est un dossier, ça veut dire que chaque dossier est lu et transformé en un fichier JSON.

Ainsi, afficher un "chapitre" = lire le manifest.json (titre, et chemin vers le JSON du chapitre qu'on veut) et le JSON du chapitre (notre conteneur). Le sommaire doit pouvoir être construit à partir du manifest.

Il ne faut pas chercher à balancer des trucs en BDD selon moi. Ce sont de grosses données, et on a déjà un tas de requêtes BDD.

qui revient aussi à de l'accès disque

les bdd travaillent beaucoup en mémoire et savent mettre des data en cache !

Ce qu'il faut optimiser, c'est le nombre de fichiers à lire. Par exemple, lors de la publication, il faut faire un fichier par conteneur et non pas un fichier pour le conteneur + 1 par extrait.

+1000 !

qui revient aussi à de l'accès disque

les bdd travaillent beaucoup en mémoire et savent mettre des data en cache !

Je sais, mais c'est dans le pire des cas :)

Ce qu'il faut optimiser, c'est le nombre de fichiers à lire. Par exemple, lors de la publication, il faut faire un fichier par conteneur et non pas un fichier pour le conteneur + 1 par extrait.

+1000 !

artragis

Encore +1000 :)

Et question d'avancer, quid de cette histoire d'intro/conclu? Le seul probleme que je vois a "tout est un extrait" c'est que ceux la serait indéplacables et n'auraient pas de titre. Dans un soucis de généricité, ca fait un cas particulier :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte