Repository: zestedesavoir/zds-site

Issue:
Les très longs tags plantent le site
Actuellement un tag a une longueur max de 20 caractères, mais ceci n'est précisé nulle part et surtout n'est pas géré par le site.

Du coup, si on tente de créer un message avec un tag de plus de 20 caractères, on a une erreur :

> DataError at /forums/sujet/nouveau/
> value too long for type character varying(20)



Discussion:
Et du coup il y a une raison de limiter la longueur des tags a une taille inférieur a celle du titre ?

> Et du coup il y a une raison de limiter la longueur des tags a une taille inférieur a celle du titre ?

Un tag étant un mot clé, si on a un tag de plus de 20 caractères on ne doit plus l'appeler tag.

Donc m'est avis que pour résoudre ce bug, il faut aller dans cette [partie du code](https://github.com/Taluu/ZesteDeSavoir/blob/dev/zds/forum/forms.py#L69) du formulaire rajouter un `elif` qui vérifie la taille du tag.

C'est normal que sur ma version local j'ai aucun probleme pour faire un tag de + de 20 car. ?

Oui : SQLite n'implémente pas les limitations de longueurs de champ...

Le 23 mai 2014 18:12, Eskimon notifications@github.com a écrit :

> C'est normal que sur ma version local j'ai aucun probleme pour faire un
> tag de + de 20 car. ?
> 
> —
> Reply to this email directly or view it on GitHubhttps://github.com/Taluu/ZesteDeSavoir/issues/590#issuecomment-44030683
> .

erf... J'y ai pensé mais j'ai pas vérifié ce fait...

Chui en train de regarder et jme demandais la meilleur conduite à avoir:
- Refuser le titre sous prétexte qu'un tag est trop long ?
- Valider le titre mais ne pas compter le tag trop long comme un tag

> Valider le titre mais ne pas compter le tag trop long comme un tag

Je pencherai plus pour cette solution.

en gros si un mec renseigne ça `[paris la meilleure des villes du monde] vrai ou faux` , le titre devra être `[paris la meilleure des villes du monde] vrai ou faux` sans tag

D'un point de vue utilisateur, j'aurais plutôt choisi l'autre solution :

> Refuser le titre sous prétexte qu'un tag est trop long ?

En effet, si l'utilisateur choisit délibérément un tag et que celui-ci est trop long, il ne comprendra pas pourquoi son tag ne passe pas. Il en aura une petite idée parce qu'il n'est pas con, mais rien ne lui assurera que c'est bien la longueur de son tag qui est en cause. Il ne saura pas non plus quelle est la limite à ne pas dépasser. Pire, il ne se rendra peut-être même pas compte que son tag n'a pas été pris en compte comme un tag.

Je pense donc qu'il est préférable de mettre un message d'erreur à la validation du formulaire indiquant que le tag choisi est trop long, en indiquant la taille max autorisée. Ainsi, l'utilisateur peut le réduire et il n'a pas de surprise.

Vu comme ça je suis d'accord avec ShigeruM
 Le 25 mai 2014 10:49, "ShigeruM" notifications@github.com a écrit :

> D'un point de vue utilisateur, j'aurais plutôt choisi l'autre solution :
> 
> Refuser le titre sous prétexte qu'un tag est trop long ?
> 
> En effet, si l'utilisateur choisit délibérément un tag et que celui-ci est
> trop long, il ne comprendra pas pourquoi son tag ne passe pas. Il en aura
> une petite idée parce qu'il n'est pas con, mais rien ne lui assurera que
> c'est bien la longueur de son tag qui est en cause. Il ne saura pas non
> plus quelle est la limite à ne pas dépasser. Pire, il ne se rendra
> peut-être même pas compte que son tag n'a pas été pris en compte comme un
> tag.
> 
> Je pense donc qu'il est préférable de mettre un message d'erreur à la
> validation du formulaire indiquant que le tag choisi est trop long, en
> indiquant la taille max autorisée. Ainsi, l'utilisateur peut le réduire et
> il n'a pas de surprise.
> 
> —
> Reply to this email directly or view it on GitHubhttps://github.com/Taluu/ZesteDeSavoir/issues/590#issuecomment-44126132
> .

Ok, donc le bloquage se fera au niveau du formulaire, ca roule !

@Eskimon n'oublie pas de t'assigner la tâche si tu t'en charge, avec ton dernier message on ne comprends pas bien si tu es sur le coup ou non, ça serait dommage que deux personnes y passent du temps :)

Oui tout a fait mais je ne sais pas pourquoi le bouton "assignee" ne fonctionne plus chez moi oO (alors que ca marchait très bien avant !!)

> mais je ne sais pas pourquoi le bouton "assignee" ne fonctionne plus chez moi oO (alors que ca marchait très bien avant !!)

Le dépot est désormais ouvert (depuis 19h 00) donc public (donc tu n'a plus les droits d'écriture ici).

Désormais, il faut forker le projet et travailler dessus. il y'aura un bout de texte qui récapitule tout ça, mais en attendant le fichier contributing est déjà utilisable.

J'en profite pour signaler que le "max_length" des tags hard-codé dans le model c'est un peu crade :-°

Disons que à peu près toutes les longueurs max des champs sont codées en
dur dans les modèles. C'est aussi ce qui est fait dans la doc Django de
mémoire.

Par contre, y'a un moyen de récupérer cette longueur, pour la mettre par
exemple dans les formulaires, pour éviter d'avoir des longueurs max
différentes dans la vue et dans le modèle.

Le 26 mai 2014 16:39, Eskimon notifications@github.com a écrit :

> J'en profite pour signaler que le "max_length" des tags hard-codé dans le
> model c'est un peu crade :-°
> 
> —
> Reply to this email directly or view it on GitHubhttps://github.com/zestedesavoir/zds-site/issues/590#issuecomment-44194617
> .

Arf ok bah vu comme ca alors... Mais oui c'était surtout dans l'optique de récupérer cette valeur dans le formulaire que je voyais la saleté arrivé... Si tu me dis qu'on peut le récupérer, dans ce cas j'ai rien dit et je vais faire en sorte que ca soit propre de mon coté pour le fix (sans toucher au modèle évidemment) :)

Je sais plus la syntaxe exacte, mais regarde dans le code des formulaires,
y'a plein d'exemples :)

Le 26 mai 2014 16:43, Eskimon notifications@github.com a écrit :

> Arf ok bah vu comme ca alors... Mais oui c'était surtout dans l'optique de
> récupérer cette valeur dans le formulaire que je voyais la saleté arrivé...
> Si tu me dis qu'on peut le récupérer, dans ce cas j'ai rien dit et je vais
> faire en sorte que ca soit propre de mon coté pour le fix (sans toucher au
> modèle évidemment) :)
> 
> —
> Reply to this email directly or view it on GitHubhttps://github.com/zestedesavoir/zds-site/issues/590#issuecomment-44194939
> .

> Je sais plus la syntaxe exacte

Pour  être plus précis, la syntaxe se trouve [ici](https://github.com/zestedesavoir/zds-site/blob/dev/zds/forum/forms.py#L20) par exemple.

^^ j'avais trouvé avant que tu interviennes mais nickel ca confirme ce que je pensais du coup :)


Resolving patch:
diff --git a/zds/forum/forms.py b/zds/forum/forms.py
--- a/zds/forum/forms.py
+++ b/zds/forum/forms.py
@@ -10,7 +10,7 @@
 from crispy_forms.helper import FormHelper
 from crispy_forms.layout import HTML
 from crispy_forms_foundation.layout import Layout, Field, Hidden
-from zds.forum.models import Forum, Topic, sub_tag
+from zds.forum.models import Forum, Topic, sub_tag, Tag
 from zds.utils.forms import CommonLayoutEditor
 
 
@@ -70,6 +70,19 @@ def clean(self):
                     .strip() == '':
                 self._errors['title'] = self.error_class(
                     [u'Le titre ne peux pas contenir uniquement des tags'])
+            else:
+                tags = re.findall(ur"((.*?)\[(.*?)\](.*?))", title)
+                for tag in tags:
+                    if tag[2].strip() == "":
+                        if 'title' in cleaned_data:
+                            self._errors['title'] = self.error_class(
+                                [u'Un tag ne peut être vide'])
+
+                    elif len(tag[2]) > Tag._meta.get_field('title').max_length:
+                        if 'title' in cleaned_data:
+                            self._errors['title'] = self.error_class(
+                                [(u'Un tag doit faire moins de {0} caractères').
+                                    format(Tag._meta.get_field('title').max_length)])
         if text is not None and text.strip() == '':
             self._errors['text'] = self.error_class(
                 [u'Le champ text ne peut être vide'])
diff --git a/zds/forum/views.py b/zds/forum/views.py
--- a/zds/forum/views.py
+++ b/zds/forum/views.py
@@ -236,12 +236,11 @@ def new(request):
             # add tags
 
             for tag in tags:
-                if tag[2].strip() != "":
-                    tg = Tag.objects.filter(slug=slugify(tag[2])).first()
-                    if tg is None:
-                        tg = Tag(title=tag[2])
-                        tg.save()
-                    n_topic.tags.add(tg)
+                tg = Tag.objects.filter(slug=slugify(tag[2])).first()
+                if tg is None:
+                    tg = Tag(title=tag[2])
+                    tg.save()
+                n_topic.tags.add(tg)
             n_topic.save()
 
             # Adding the first message
@@ -621,12 +620,11 @@ def edit_post(request):
                 # add tags
 
                 for tag in tags:
-                    if tag[2].strip() != "":
-                        tg = Tag.objects.filter(slug=slugify(tag[2])).first()
-                        if tg is None:
-                            tg = Tag(title=tag[2])
-                            tg.save()
-                        g_topic.tags.add(tg)
+                    tg = Tag.objects.filter(slug=slugify(tag[2])).first()
+                    if tg is None:
+                        tg = Tag(title=tag[2])
+                        tg.save()
+                    g_topic.tags.add(tg)
                 g_topic.save()
         post.save()
         return redirect(post.get_absolute_url())


Test patch: