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.

Bon, pierre et moi on a commencé à coder. On y va à notre rythme, cette zep étant juste immense, mais juste un petit indicateur :

nous avons théoriquement migré les fonctionnalités suivantes :

  • afficher un tutoriel/article offline (avec le formulaire d'édition)
  • afficher un tutoriel/article en béta (donc ajout de fonctionnalité côté article !)
  • afficher un tutoriel/article online (avec le formulaire de réaction)

Et nous avons pour ces deux modules réunis 30 lignes de moins que le module de tuto seul (à fonctionnalité égale, mais avec plus de commentaires oO)

C'est pour montrer combien la duplication de code était immense. Là on va vraiment aller vers une base saine !

Hesitez pas a mettre des docstring sur les fonctions (on en manque) et n'hésitez pas non plus a continuer a donner l'avancement : je vais en avoir besoin pour la zep5 qui est lié indirectement (elle se charge de transformer un tuto en pdf ou ebook).

D'ailleurs ne vous occupez pas des fonctions d'exports.

Hesitez pas a mettre des docstring sur les fonctions (on en manque)

C'est en cours, mais j'ajoute ça au fur et à mesure. Là, je suis dans le modèle. Tient, question, je doit préciser :type et :rtype ou pas ?

et n'hésitez pas non plus a continuer a donner l'avancement : je vais en avoir besoin pour la zep5 qui est lié indirectement (elle se charge de transformer un tuto en pdf ou ebook).

D'ailleurs ne vous occupez pas des fonctions d'exports.

Kje

Loin de moi cette idée saugrenue d'aller toucher à ces fonctions là :p

Vous passez sur du CBV ?

gustavi

Atragis fait ça, oui, il est sur la vue, principalement pour le moment :)

+1 -0

Vous passez sur du CBV ?

gustavi

Oui, nous passons sur du CBV pour deux raisons :

  • factorisation des vues non négligeables, les listes de contenus qui ne diffèrent que par le type de contenu (donc le filtre appliqué) ne méritent pas une fonction par liste.
  • permet de rendre la ZEP-12 API-ready pour que votre travail ne soit pas vain sur la partie membre.

J'ai des questions et remarques :

  1. C'est quoi "CBV" ?
  2. A propos des commentaires :
    • Est-ce que vous pouvez jeter un oeil à cette PR et me dire si ce que j'ai fait est cohérent avec les conventions et le niveau de détail que vous utilisez ?
    • Normalement j'ai prévu de ne pas commenter les classes touchées par cette PR

C'est quoi "CBV" ?

désolé pour l'acronyme à trois lettre ^^.

CBV pour Class Based View. En fait ce sont des class générant des vues qui héritent de classes déjà créés dans django. Du coup une grande partie du code qu'on avait avant dans nos fonctions ultra longue est déjà en natif de django, nous on n'a plus qu'à paramétrer. C'est ce qu'il se passe sur les vues de listes qui ressemblent du coup à ça :

 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
class ArticleList(ListView):
    """
    Displays the list of published articles.
    """
    context_object_name = 'articles'
    paginate_by = settings.ZDS_APP['tutorial']['content_per_page']
    type = "ARTICLE"
    template_name = 'article/index.html'
    tag = None

    def get_queryset(self):
        """
        Filter the content to obtain the list of only articles. If tag parameter is provided, only articles
        which have this category will be listed.
        :return: list of articles
        """
        if self.request.GET.get('tag') is not None:
            self.tag = get_object_or_404(SubCategory, title=self.request.GET.get('tag'))
        query_set = PublishableContent.objects.filter(type=self.type).filter(sha_public__isnull=False)\
            .exclude(sha_public='')
        if self.tag is not None:
            query_set = query_set.filter(subcategory__in=[self.tag])
        return query_set.order_by('-pubdate')

    def get_context_data(self, **kwargs):
        context = super(ArticleList, self).get_context_data(**kwargs)
        context['tag'] = self.tag
        return context

class TutorialList(ArticleList):
    """Displays the list of published tutorials."""

    context_object_name = 'tutorials'
    type = "TUTORIAL"
    template_name = 'tutorial/index.html'

La liste des articles et des tutoriels en CBV

à la place de :

 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
def index(request):
    """Display all public articles of the website."""
    # The tag indicate what the category article the user would
    # like to display. We can display all subcategories for articles.
    try:
        tag = get_object_or_404(SubCategory, title=request.GET['tag'])
    except (KeyError, Http404):
        tag = None

    if tag is None:
        articles = Article.objects\
            .filter(sha_public__isnull=False).exclude(sha_public="")\
            .order_by('-pubdate')\
            .all()
    else:
        # The tag isn't None and exist in the system. We can use it to retrieve
        # all articles in the subcategory specified.
        articles = Article.objects\
            .filter(sha_public__isnull=False, subcategory__in=[tag])\
            .exclude(sha_public="").order_by('-pubdate')\
            .all()

    article_versions = []
    for article in articles:
        article_version = article.load_json_for_public()
        article_version = article.load_dic(article_version)
        article_versions.append(article_version)

    return render(request, 'article/index.html', {
        'articles': article_versions,
        'tag': tag,
    })

def index(request):
    """Display all public tutorials of the website."""

    # The tag indicate what the category tutorial the user would like to
    # display. We can display all subcategories for tutorials.

    try:
        tag = get_object_or_404(SubCategory, slug=request.GET["tag"])
    except (KeyError, Http404):
        tag = None
    if tag is None:
        tutorials = \
            Tutorial.objects.filter(sha_public__isnull=False).exclude(sha_public="") \
            .order_by("-pubdate") \
            .all()
    else:
        # The tag isn't None and exist in the system. We can use it to retrieve
        # all tutorials in the subcategory specified.

        tutorials = Tutorial.objects.filter(
            sha_public__isnull=False,
            subcategory__in=[tag]).exclude(sha_public="").order_by("-pubdate").all()

    tuto_versions = []
    for tutorial in tutorials:
        mandata = tutorial.load_json_for_public()
        tutorial.load_dic(mandata)
        tuto_versions.append(mandata)
    return render(request, "tutorial/index.html", {"tutorials": tuto_versions, "tag": tag})

vues à l'ancienne

sachant que, par exemple, pour utiliser la ZEP 3, l'implémentation se contentera d'une classe style

1
2
3
4
5
6
7
8
9
class TutorialWithHelp(TutorialList):
    context_object_name = 'tutorials'
    template_name = 'tutorial/help.html'
    def get_queryset(self):
        return PublishableContent.objects.exclude(Q(helps_count=0) and Q(sha_beta=''))
    def get_context_data(self, **kwargs):
        context = super(TutorialWithHelp, self).get_context_data(**kwargs)
        context['helps'] = HelpWritting.objects.all()
        return context

Ce à quoi ressemblerait la liste ZEP03

Il manque juste l'implémentation du filtre mais tu vois le genre?

+5 -0

Bon :)

Le développement avançant, j'ai tenté de mettre en place une des idées qui me tient le plus à cœur avec cette ZEP : une gestion "plus intelligente" des versions.

Je m'explique : actuellement, on a une sorte de ligne du temps dans lequel les "jalons" sont les commits effectués par les auteurs. Pour chacun de ces commits, on a une arborescence, qui varie d'une fois à l'autre, et un "manifest.json", qui est le fichier qui reprend tout ça et qui change lui aussi à chaque version. D'autre part, toujours actuellement, on tente de faire coller chaque "objet" à une représentation en base de donnée (les Chapitres, Parties, Extraits et s'en suis).

Problème selon moi avec ça, c'est qu'une base de donnée n'est pas versionnée, ce qui signifie que si entre la version "publiée" et "brouillon" du tutoriel, une partie à changé de titre, impossible de régénérer l'URL de la version "publiée" à partir des informations en base de donnée (qui correspondent TOUJOURS à la version "brouillon"), ça ne marchera pas. Ce qu'on fait actuelement, c'est d'aller rechercher dans l'historique du tutoriel la version correspondante avec le bon titre, et on est sauvé.

Dès lors, après réflexion, je me suis dit que ça ne servait absolument plus à rien de stocker ces objets en base de donnée: puisque c'est quand même pour aller choper dans l'historique git à chaque fois, autant ne pas se casser la tête avec des trucs en base de donnée. J'ai donc codé une PR relativement importante qui met en place cette histoire. Si je simplifie, voilà comment ça se passe:

  • On a un objet qui d'une part correspond à une ligne de table. Cette table reprend les informations non-versionnées (actuelement) et liées à d'autres éléments eux-même en base de donnée, telle que les auteurs, les catégories, les notes, et ainsi de suite. Cette base de donnée reprend également les hash de chacune des versions que compte le tuto (brouillon, bêta, validation, publique). Pour chaque opération qu'on cherche à faire, ce objet est de toute façon récupéré (c'est déjà le cas actuellement).
  • D'autre part, on a tout les objets que cet ZEP prétend mettre en place (Conteneur et Extrait). Dès lors pour une version donnée ("brouillon", par exemple), on récupère le "manifest.json" correspondant, on génère toute la structure et on travaille là dessus. Dès lors, les informations contenues dans ces données correspondent aux informations de la version ! Plus de problème de modification de titre ou quoique ce soit, il suffit de travailler avec la bonne version. Et pas besoin de stocker tout ça en base de donnée.

Dès lors, la base de donnée n'est modifiée que si on touche à une de ces informations en relation avec d'autres éléments en base de donnée ou quand on change un des hash.

En fait, ça marche assez bien. En codant tout ça, j'ai fait différents tests et ça se comporte assez bien, je pense réellement qu'on peut gagner en stabilité et en mobilité avec ça (entre autre, c'est une ÉNORME simplification pour la ZEP-08, parce que tout ce qui est "tripoter des versions" se retrouve beaucoup plus localisé qu'avant).

Mais si je viens discuter ici, c'est d'une part pour recueillir votre approbation, d'autre part pour énoncer le point que j'ai soigneusement évité d'aborder jusqu'ici parce que je sais qu'il va faire débat (parce qu'il a déjà fait débat) : puisqu'on ne stocke plus les objets en base de donnée, ils n'ont plus de clé uniques (le fameux pk). Je vais tout de même modérer cette affirmation, puisque le "containeur principal" (aka l'article ou le tuto, dans le langage de la ZEP-12) conserve un pk, puisque certaines de ces informations restent conservée en base de donnée, et je ne compte pas que ça change. Reste donc le cas des sous-conteneurs (partie, chapitre) et des (extraits), qui n'en ont plus.

Dans l'implémentation que j'en ai fait, je les conserve : on en a besoin pour la rétro-compatibilité des urls (qui s'annonce relativement plus simple que je ne l'aurait cru) et tout simplement parce qu'il faut éviter que deux extraits ayant le même slug ne s'écrasent mutuellement, ce pourquoi ils sont dans les urls et les noms de fichier. Ce que j'apelle pk revient alors à une clé nominale qui se veut être unique. "Problème", puisqu'on fait pas appel à la base de donnée, il faut ruser pour que ça soit effectivement le cas.

Bref,

  • Est ce qu'à part le problème de clé nominale, quelqu'un voit l'intérêt de continuer à stocker les objets en BDD ? Si oui, pourquoi ?
  • Dans le cas contraire, comment faire en sorte que la clé nominale le soit effectivement bien sans se prendre la tête ? (un sujet qui tient énormément à coeur Firm1 )

Pour plus d'informations, voir la PR correspondante sur le dépot d'artragis

Est ce qu'à part le problème de clé nominale, quelqu'un voit l'intérêt de continuer à stocker les objets en BDD ? Si oui, pourquoi ?

j'ai toujours été contre une clef nominale. Au départ le but était de dédoublonner la création de fichier. Ma première implémentation (à l'époque de la béta fermée, ça date :o)) avait été simplement de dire "si je trouve un fichier du même nom j'ajoute p1_ devant le nom du fichier, puis p2_ etc.

Firm1 y avait regardé et avait dit que c'était crade et pas ACID alors il fallait qu'on use de ruse et qu'on passe à la pk.

Personnellement ça m'a toujours fait chier et j'ai la profonde certitude que ça a causé énormément d'instabilités dans le module de tutoriel aux débuts du site.

Aujourd'hui, notre modèle est tout beau, notre vue se fait un lifting mode on "change bien plus que les pièces détachées", la logique sous-jacente a déjà eu quelques apports de simplification mais la pk nous dérange. Il faut qu'on sache si on doit garder cette contrainte ou bien si on peu en faire fi car c'est has been ^^

D'autre part, on a tout les objets que cet ZEP prétend mettre en place (Conteneur et Extrait). Dès lors pour une version donnée ("brouillon", par exemple), on récupère le "manifest.json" correspondant, on génère toute la structure et on travaille là dessus. Dès lors, les informations contenues dans ces données correspondent aux informations de la version ! Plus de problème de modification de titre ou quoique ce soit, il suffit de travailler avec la bonne version. Et pas besoin de stocker tout ça en base de donnée.

Je n'ai pas tout suivi, mais est-ce que cela signifie que l'on pourrait ajouter des extraits ou des conteneurs enfant en mode hors-ligne ? Si oui, j'approuve à mort cette possibilité !

Sinon, créer un entier de manière un peu unique pour l'URL, ça ne doit pas être si compliqué que ça, quitte a avoir un index des titres existant en BDD ou dans un fichier.

+0 -0

Je n'ai pas tout suivi, mais est-ce que cela signifie que l'on pourrait ajouter des extraits ou des conteneurs enfant en mode hors-ligne ? Si oui, j'approuve à mort cette possibilité !

oui, je veux pouvoir le faire ça. Et pierre aussi. On veut tous pouvoir le faire.

créer un entier de manière un peu unique pour l'URL

en fait c'est pas pour l'url c'est pour le fichier/dossier stocké dans le filesystem.

+0 -0

Je n'ai pas tout suivi, mais est-ce que cela signifie que l'on pourrait ajouter des extraits ou des conteneurs enfant en mode hors-ligne ? Si oui, j'approuve à mort cette possibilité !

oui, je veux pouvoir le faire ça. Et pierre aussi. On veut tous pouvoir le faire.

Oh que oui ;)

créer un entier de manière un peu unique pour l'URL

en fait c'est pas pour l'url c'est pour le fichier/dossier stocké dans le filesystem.

artragis

Il se trouve que le système de fichier et l'url correspondent, pour des raisons pratiques ;)

Hmmm, là comme ça je ne vois pas d'inconvénient majeur, à condition que :

  1. On gère parfaitement les conversions des tutos déjà existants. Ça implique les cas pathologiques.
  2. On a des performances au moins équivalentes à celles d'aujourd'hui ; sachant que les performances des I/O disque sont notre gros point noir.
  3. Qu'on réponde explicitement aux arguments avancés en faveur des PK à l'époque.

Pour ce dernier point, je précise toutefois :

  • Que si on peut revoir les URLs avec cette ZEP, c'est une bonne chose. Une URL du type https://zestedesavoir.com/tutoriels/187/creez-votre-application-web-avec-java-ee/214/les-bases-du-java-ee/1303/le-java-ee-mis-a-nu/#3-le-modele-mvc-en-pratique devrait être quelque chose comme https://zestedesavoir.com/tutoriels/creez-votre-application-web-avec-java-ee/les-bases-du-java-ee/le-java-ee-mis-a-nu/#3-le-modele-mvc-en-pratique (je garde le 3 dans l'ancre qui n'est pas affiché, mais qui pourrait, puisque c'est le 3ème titre de la page)
  • Ceci implique que un slug est unique au moins au sein du même tuto. Je ne comprends même pas pourquoi ce n'est pas le cas aujourd'hui. Ceci nullifie cet argument : "si pour la lecture d'un tutoriel on se base sur le slug contenu dans l'url, il suffit que deux tutoriels/sections/extraits ait le même slug pour que j'accède au tutoriel de quelqu'un d'autre."
  • Ce point doit être géré : "lorsqu'on voudra implémenter le déplacement d'un extrait d'un tutoriel à un autre, on sera bien embêté lorsqu'on se rendra compte qu'il y'a conflit entre les clés d'identification.".
  • Ceci par contre, je suis contre : "L'auteur a le droit de structurer son dépot comme il le veut, et le site ne doit pas venir casser sa structure, ni la refuser, mais il doit s'adapter à sa structure, donc il faut que la technique s'adapte au modèle de l'auteur.". On ne va pas s'amuser à faire un code ultra-compliqué pour gérer des cas pathologiques d'auteurs qui auront voulu faire n'importe quoi. Bien entendu on doit rester souples pour accepter un minimum de cas. Mais par exemple je n'ai aucun problème à imposer que les slugs soient uniques dans tout le tuto. On peut donc refuser un modèle trop cassé.

Billes techniques :

Donc, après discussion de tout ça sur IRC, petit résumé + réflexions personnelles (à noter qu'actuelement, le manifest.json généré ressemble à ça, j'ai pas encore arrêté sa forme définitive):

  • Le premier point à régler est l'unicité des slugs. Les slugs des conteneurs/extraits doivent être unique dans un tuto/article, et les slugs en BDD doivent l'être également. Ça implique coté BDD d'utiliser une des librairies proposées par SpaceFox (mais il faut tout d'abord que quelqu'un qui a accès à la base de prod' me confirme que tout les slugs des tutoriels sont bien uniques), et coté conteneur/extrait de garder quelque part une liste des slugs employés (dans le containeur principal, par exemple) et de la consulter à chaque fois qu'on souhaite créer un slug. Il faut également bien faire attention que les slugs "introduction" et "conclusion" sont déjà employés pour les fichiers du même nom.

    Ça implique également que le slug va devoir être conservé dans le manifest.json, alors qu’actuellement, il est généré à la demande à partir du titre (d'ailleurs, comme ça, on s'assure qu'il ne change pas d'une fois à l'autre). Ça implique aussi qu'on peut dégager le pk puisqu'il ne servira plus à rien (à la limite, le conserver pour le conteneur principal). Ça implique finalement qu'il faut bien vérifier ce qui se passe avec intro/conclusion.

    Et je n'ai aucun scrupule à refuser des manifest.json dans lequel le slug serait pas unique. Ceci dit, il faudra bien vérifier qu'il s'agit effectivement d'un slug (aka qu'il ne contient que des caractère alphanumériques sans accents et des tirets).

  • Actuellement, la manière d'afficher les tutos publiés n'est absolument pas optimale : on fait une copie de repository git pour ne jamais s'en servir, on passe systématiquement par git alors que c'est peut-être pas nécessaire et on a 3 fichiers par chapitre (le texte, l'intro éventuelle et la conclusion éventuelle). Il a donc été proposé de rassembler tout ça en un, de ne plus avoir à employer git pour cette partie là (ce qui est logique, rien de versionné là dedans) et de se baser un maximum sur l'affichage de fichiers statiques.

    Artragis a également proposé qu'on aie plus besoin du tout du manifest.json pour la version publiée. À réflexion (la nuit porte conseil), ça risque de poser problème pour plusieurs points : le sommaire (mais il suffit de l'exporter aussi), les précédents/suivants des chapitres (ça aussi ça peut s'exporter), mais aussi et surtout selon moi deux gros points : si on fait ça, plus moyen de faire de modification de la template du tuto à postériori, ce qui signifie que, j'invente, on corrige une faute d'orthographe à "suivant", il faudrait regénérer tout les tutos/articles déjà en ligne, ce qui devient un peu pénible. L'autre point qui me pose problème, c'est que le site ne sais à priori pas ou il se trouve dans le tutoriel, donc des informations comme le titre du tuto/partie/chapitre, il n'en sais rien et pas moyen de s'en sortir. Dès lors, pour moi, le manifest.json reste nécessaire pour la version publiée MAIS il y a moyen de faire en sorte que l'affichage se fasse plus vite, puisque la résolution d'URL revient à vérifier que le fichier statique correspondant existe et le manifest.json n'est nécessaire que pour connaitre le "contexte" dans lequel on se trouve, donc se passer de git quoiqu'il arrive.

  • Je me rend compte que je sais très exactement de quoi je parle, mais que vu de l'extérieur, je parle chinois. Je vais donc tenter de rédiger une petite documentation avec la ZEP (oui, dans Sphinx) pour expliquer comment tout ça se passe et doit se passer.

+1 -0

Je ne suis absolument pas fan de devoir gérer des "pk" dans le manifest. Il devrait se situer en BDD (donc pour le container root), mais ce n'est pas a mettre dans le manifest. Pourquoi ? Pour y répondre, deux question : - Que se passe-t-il si l'user met un truc fantasiste dedans ? - Une clé qui ne lui appartient pas ?

Et de toutes manières, comme ça a déjà été soulevé à plusieurs reprises (la flemme de chercher, mais il me semble que c'est principalement dans ce même topic), il faut séparer les infos de la BDD et du manifest. En gros, ne conserver en BDD que les infos utiles pour le tuto (soit evntuellement, sa PK, ses hashs (rédaction, validation, en ligne, …), et dans le manifest la structure, l'ordre, les titres…

Aussi, je suis pas fan de la clé "obj_type". Pourquoi pas "type" tout court ? Et d'ailleurs, pourquoi ne pas tenter d'extrapoler cette info suivant le nombre de container enfant et roots (suffit de voir s'ils contiennent une intro / conclusion pour les différencier), avec ce genre de répartition :

  • mini : $n = 0$
  • moyen : $n = 1$
  • big : $n > 1$
+0 -0

Je ne suis absolument pas fan de devoir gérer des "pk" dans le manifest. Il devrait se situer en BDD (donc pour le container root), mais ce n'est pas a mettre dans le manifest. Pourquoi ? Pour y répondre, deux question : - Que se passe-t-il si l'user met un truc fantasiste dedans ? - Une clé qui ne lui appartient pas ?

J'approuve, effectivement. Et comme de toute façon y vont sortir, bah … Voilà.

Et de toutes manières, comme ça a déjà été soulevé à plusieurs reprises (la flemme de chercher, mais il me semble que c'est principalement dans ce même topic), il faut séparer les infos de la BDD et du manifest. En gros, ne conserver en BDD que les infos utiles pour le tuto (soit evntuellement, sa PK, ses hashs (rédaction, validation, en ligne, …), et dans le manifest la structure, l'ordre, les titres…

C'est très exactement pour ça qu'on fait autant de bruit ces quelques derniers jours. Maintenant qu'on a l'accord de SpaceFox, y'a plus qu'a paufiner un peu l'aspect technique (tenir compte des remarques qui ont été faites), mais c'est en bonne voie.

Aussi, je suis pas fan de la clé "obj_type". Pourquoi pas "type" tout court ?

Déjà soulevé par SpaceFox, et en effet, y'a pas de raison que ça ne soit pas "type" tout cours.

Et d'ailleurs, pourquoi ne pas tenter d'extrapoler cette info suivant le nombre de container enfant et roots (suffit de voir s'ils contiennent une intro / conclusion pour les différencier), avec ce genre de répartition :

  • mini : $n = 0$
  • moyen : $n = 1$
  • big : $n > 1$

Talus

Y'a déjà un truc comme ça qui a été tenté, qu'artragis a nommé tree_depth pour différencier les différents types de tutoriels et s'assurer qu'on ne met pas trop de container. Du reste, l'extrapolation peut être une bonne idée, mais je préfère quand même indiquer explicitement le type, pour la simple et bonne raison que l'intro et la conclusion sont facultative (je crois qu'actuelement le fichier est créé et la clé rajoutée au manifest quand même, mais à vérifer), donc se reposer entièrement là dessus me semble tendu. À la limite, j'aurais plus tendance à me reposer sur l'absence de clé "text" (un extrait sans clé "text" n'ayant vraiment aucun sens). Du coup j'hésite … "type" ou pas ? (sachant qu'il faut garder une clé "type" pour différencier artricle et tuto dans le container principal).

Ben le but serait de les enlever (spécialement vis à vis de la ZEP-8). Et pour le slug, comme ça déjà été mentionné, pourquoi ne pas générer une sorte de path via le manifest + les titles qu'on transforme en slug ?

Y'a déjà un truc comme ça qui a été tenté, qu'artragis a nommé tree_depth pour différencier les différents types de tutoriels et s'assurer qu'on ne met pas trop de container. Du reste, l'extrapolation peut être une bonne idée, mais je préfère quand même indiquer explicitement le type, pour la simple et bonne raison que l'intro et la conclusion sont facultative (je crois qu'actuelement le fichier est créé et la clé rajoutée au manifest quand même, mais à vérifer), donc se reposer entièrement là dessus me semble tendu. À la limite, j'aurais plus tendance à me reposer sur l'absence de clé "text" (un extrait sans clé "text" n'ayant vraiment aucun sens). Du coup j'hésite … "type" ou pas ? (sachant qu'il faut garder une clé "type" pour différencier artricle et tuto dans le container principal).

pierre_24

Ah mais je parlais du type de tuto, pas du conteneur. Du coup pour l'instant je viens de comprendre la diff entre "type" et "obj_type", mais en effet, si on extrapole (au pire, indiquer qu'on peut renseigner le type du tuto, qui prend alors précédence, avec une validation - un mini-tuto ne peut pas avoir de sous-conteneur, tout comme un moyen a besoin d'un (et un seul) conteneur, et un big d'au moins un).

Mais après du coup, comment savoir, lorsqu'on lit un conteneur, s'il s'agit d'un type de tuto (s'il est root) ou bien d'un type de conteneur ?

+0 -0

Ben le but serait de les enlever (spécialement vis à vis de la ZEP-8).

Bien recu :)

Et pour le slug, comme ça déjà été mentionné, pourquoi ne pas générer une sorte de path via le manifest + les titles qu'on transforme en slug ?

Parce que si pour une raison deux etraits ont le même slug dans le même conteneur (oui, c'est tordu mais ça peut arriver), on a de la collision quand même. Ou j'ai pas compris :) (en plus du fait que ça va faire des slugs supers-longs :o )

Ah mais je parlais du type de tuto, pas du conteneur. Du coup pour l'instant je viens de comprendre la diff entre "type" et "obj_type", mais en effet, si on extrapole (au pire, indiquer qu'on peut renseigner le type du tuto, qui prend alors précédence, avec une validation - un mini-tuto ne peut pas avoir de sous-conteneur, tout comme un moyen a besoin d'un (et un seul) conteneur, et un big d'au moins un).

Je te corrige, mais on peut mettre plusieurs conteneur (=chapitre) dans un moyen tuto ;)

Mais après du coup, comment savoir, lorsqu'on lit un conteneur, s'il s'agit d'un type de tuto (s'il est root) ou bien d'un type de conteneur ?

Talus

Parce qu'il est "root", justement. Mais pour mettre tout le monde d'accord, pourquoi pas appeller cette clé "object", tout simplement ?

Ben le but serait de les enlever (spécialement vis à vis de la ZEP-8).

Bien recu :)

pierre_24

Je répondais a SpaceFox. :D

Et pour le slug, comme ça déjà été mentionné, pourquoi ne pas générer une sorte de path via le manifest + les titles qu'on transforme en slug ?

Parce que si pour une raison deux etraits ont le même slug dans le même conteneur (oui, c'est tordu mais ça peut arriver), on a de la collision quand même. Ou j'ai pas compris :) (en plus du fait que ça va faire des slugs supers-longs :o )

pierre_24

Sauf que je doute que quelqu'un utilise deux fois le meme titre au sein d'un même parent direct… Et au pire, LIFO. Et osef des titres longs ; il est plus facile de divulguer /tuto/tuto-cool/partie-cool/#sous-partie-cool que /tuto/asjv29-3554b-sgv-dt-4543-fbfdgrdd/4533-lbbngrde/#fjeiofjes, non ? :)

Ah mais je parlais du type de tuto, pas du conteneur. Du coup pour l'instant je viens de comprendre la diff entre "type" et "obj_type", mais en effet, si on extrapole (au pire, indiquer qu'on peut renseigner le type du tuto, qui prend alors précédence, avec une validation - un mini-tuto ne peut pas avoir de sous-conteneur, tout comme un moyen a besoin d'un (et un seul) conteneur, et un big d'au moins un).

Je te corrige, mais on peut mettre plusieurs conteneur (=chapitre) dans un moyen tuto ;)

pierre_24

Après clarification avec moi même (oui on est plusieurs là dedans :D), il faut voir si on a une et une seule conteneur en tant qu'enfant du root (donc enfant direct), mais après libre a ce sous-conteneur d'avoir plusieurs conteneurs… Un mini-tuto lui ne devrait avoir que des extracts, alors qu'un big-tuto doit avoir au moins un conteneur.

Mais après du coup, comment savoir, lorsqu'on lit un conteneur, s'il s'agit d'un type de tuto (s'il est root) ou bien d'un type de conteneur ?

Talus

Parce qu'il est "root", justement. Mais pour mettre tout le monde d'accord, pourquoi pas appeller cette clé "object", tout simplement ?

pierre_24

Du coup, niveau nomenclature, je trouverai ça plus logique d'avoir une clé optionnelle "type" dans le conteneur root, qui définit le type du tuto (sinon il doit pouvoir être extrapolé), puis des clés "object", optionnelles (encore une fois, un truc extrapollable) aussi, qui indique le type de conteneur

+2 -0
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