Skip to content

Commit

Permalink
Ajout d'un système de labellisation (#6462)
Browse files Browse the repository at this point in the history
Co-authored-by: Alexandre Bertin <abertin002@enseirb-matmeca.fr>
  • Loading branch information
victorlohezic and Alexandre Bertin authored Apr 27, 2023
1 parent a1fccea commit e3da299
Show file tree
Hide file tree
Showing 20 changed files with 482 additions and 0 deletions.
25 changes: 25 additions & 0 deletions fixtures/labels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
- model: tutorialv2.Label
pk: 1
fields:
name: Les plus lus
description: Les contenus les plus visités du site.
slug: populaires
- model: tutorialv2.Label
pk: 2
fields:
name: Les mieux notés
description: Les contenus les mieux notés du site.
slug: note
- model: tutorialv2.Label
pk: 3
fields:
name: A ne pas manquer
description: Contenu jugé intéressant par un grand nombre de personnes.
slug: manquer
- model: tutorialv2.Label
pk: 4
fields:
name: Suggestion
description: Contenu suggéré par l'équipe de développement.
slug: suggestion

2 changes: 2 additions & 0 deletions templates/tutorialv2/events/descriptions.part.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
{% elif event.type == "goals_management" %}
<a href="{{ performer_href }}">{{ event.performer }}</a> a modifié les objectifs du contenu.

{% elif event.type == "labels_management" %}
<a href="{{ performer_href }}">{{ event.performer }}</a> a modifié les labels du contenu.

{% elif event.type == "suggestions_management" %}
{% if event.action == "add" %}
Expand Down
7 changes: 7 additions & 0 deletions templates/tutorialv2/includes/editorialization.part.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ <h3>Éditorialisation</h3>
</a>
{% crispy form_edit_goals %}
</li>

<li>
<a href="#edit-labels" class="open-modal ico-after gear blue">
{% trans "Modifier les labels" %}
</a>
{% crispy form_edit_labels %}
</li>
{% endif %}

{% if is_staff and not content.is_opinion %}
Expand Down
12 changes: 12 additions & 0 deletions templates/tutorialv2/includes/labels.part.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% load i18n %}

{% if labels %}
<p>
{% trans "Label" %}{{ labels|pluralize }}{%trans " :" %}
{% comment %}
Warning: whitespace in the loop below is crucial to ensure correct rendering.
That's why it is written as a one-liner. Take care when modifying it.
{% endcomment %}
{% for label in labels %}{% if not forloop.first %}, {% endif %}<a href="{% url 'content:view-labels' label.slug %}">{{ label }}</a>{% endfor %}
</p>
{% endif %}
2 changes: 2 additions & 0 deletions templates/tutorialv2/includes/tags_authors.part.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@

{% include "tutorialv2/includes/goals.part.html" with goals=publishablecontent.goals.all %}

{% include "tutorialv2/includes/labels.part.html" with labels=publishablecontent.labels.all %}

{% if online and not is_part_or_chapter %}
<p>{% blocktrans with reading_time=reading_time|humanize_duration %}Temps de lecture estimé à {{ reading_time }}.{% endblocktrans %}</p>
{% endif %}
Expand Down
59 changes: 59 additions & 0 deletions templates/tutorialv2/labels/view_labels.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{% extends "base.html" %}
{% load profile %}
{% load thumbnail %}
{% load date %}
{% load i18n %}
{% load captureas %}
{% load times %}


{% block title %}
{{ headline }}
{% endblock %}


{% block breadcrumb %}
<li>{{ headline }}</li>
{% endblock %}

{% block headline %}
{{ headline }}
{% endblock %}

{% block sidebar %}
<div class="sidebar">
<div class="mobile-menu-bloc mobile-all-links" data-title="Filtrer">
<h3>Filtrer</h3>
<ul>
{% for label in labels %}
<li>
<a href="{% url 'content:view-labels' label.slug %}" class="{% if current_filter_pk == label.pk %}selected{% endif %}">{{ label.name }} ({{ label.num_contents }})</a>
</li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}

{% block content %}
<section class="flexpage-wrapper">
{% if current_description %}
<p>{{ current_description }}</p>
{% endif %}
{% if not contents %}
<p>{% trans "Il n'y a pas de publication avec ce label." %}</p>
{% else %}
{% include "misc/paginator.html" with position="top" %}
<div class="content-item-list">
{% for content in contents %}
{% include "tutorialv2/includes/content_item.part.html" with public_content=content.public_version show_description=True show_reactions=True ignore_categories=ignore_categories %}
{% endfor %}
{% for i in 1|times %}
<div class="fill"></div>
{% endfor %}
</div>
{% include "misc/paginator.html" with position="bottom" %}
{% endif %}

</section>
{% endblock %}
1 change: 1 addition & 0 deletions zds/settings/abstract_base/zds.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
"suggestions_per_page": 2,
"mass_edit_goals_content_per_page": 25,
"view_contents_by_goal_content_per_page": 42,
"view_contents_by_label_content_per_page": 42,
"feed_length": 5,
"user_page_number": 5,
"default_image": BASE_DIR / "fixtures" / "noir_black.png",
Expand Down
7 changes: 7 additions & 0 deletions zds/tutorialv2/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
)
from zds.tutorialv2.models.events import Event
from zds.tutorialv2.models.goals import Goal
from zds.tutorialv2.models.labels import Label
from zds.tutorialv2.models.help_requests import HelpWriting


Expand Down Expand Up @@ -119,6 +120,11 @@ class GoalAdmin(admin.ModelAdmin):
ordering = ["position"]


class LabelAdmin(admin.ModelAdmin):
list_display = ["name", "description"]
ordering = ["name"]


admin.site.register(PublishableContent, PublishableContentAdmin)
admin.site.register(PublishedContent, PublishedContentAdmin)
admin.site.register(Validation, ValidationAdmin)
Expand All @@ -130,4 +136,5 @@ class GoalAdmin(admin.ModelAdmin):
admin.site.register(HelpWriting)
admin.site.register(Event)
admin.site.register(Goal, GoalAdmin)
admin.site.register(Label, LabelAdmin)
admin.site.register(ContentSuggestion)
47 changes: 47 additions & 0 deletions zds/tutorialv2/migrations/0037_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Django 3.2.15 on 2023-04-20 23:29

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("tutorialv2", "0036_alter_contentsuggestion_options"),
]

operations = [
migrations.CreateModel(
name="Label",
fields=[
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("name", models.CharField(help_text="Nom du label", max_length=80, verbose_name="Nom")),
(
"description",
models.TextField(blank=True, help_text="Description du label", verbose_name="Description"),
),
(
"slug",
models.SlugField(
help_text="L'URL pour voir les contenus associés au label est de la forme contenus/labels/slug",
max_length=80,
unique=True,
),
),
],
options={
"verbose_name": "Label",
"verbose_name_plural": "Labels",
},
),
migrations.AddField(
model_name="publishablecontent",
name="labels",
field=models.ManyToManyField(
blank=True,
db_index=True,
related_name="contents",
to="tutorialv2.Label",
verbose_name="Labels du contenu",
),
),
]
5 changes: 5 additions & 0 deletions zds/tutorialv2/models/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from zds.tutorialv2.managers import PublishedContentManager, PublishableContentManager, ReactionManager
from zds.tutorialv2.models import TYPE_CHOICES, STATUS_CHOICES, CONTENT_TYPES_REQUIRING_VALIDATION, PICK_OPERATIONS
from zds.tutorialv2.models.goals import Goal
from zds.tutorialv2.models.labels import Label
from zds.tutorialv2.models.mixins import TemplatableContentModelMixin, OnlineLinkableContentMixin
from zds.tutorialv2.models.versioned import NotAPublicVersion
from zds.tutorialv2.utils import get_content_from_json, BadManifestError, get_blob
Expand Down Expand Up @@ -78,6 +79,10 @@ class Meta:
Goal, verbose_name="Objectifs du contenu", blank=True, db_index=True, related_name="contents"
)

labels = models.ManyToManyField(
Label, verbose_name="Labels du contenu", blank=True, db_index=True, related_name="contents"
)

# store the thumbnail for tutorial or article
image = models.ForeignKey(Image, verbose_name="Image du tutoriel", blank=True, null=True, on_delete=models.SET_NULL)

Expand Down
11 changes: 11 additions & 0 deletions zds/tutorialv2/models/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from zds.tutorialv2.views.contributors import AddContributorToContent, RemoveContributorFromContent
from zds.tutorialv2.views.editorialization import EditContentTags, AddSuggestion, RemoveSuggestion
from zds.tutorialv2.views.goals import EditGoals
from zds.tutorialv2.views.labels import EditLabels
from zds.tutorialv2.views.help import ChangeHelp
from zds.tutorialv2.views.validations_contents import (
ReserveValidation,
Expand Down Expand Up @@ -47,6 +48,7 @@
signals.validation_management: "validation_management",
signals.tags_management: "tags_management",
signals.goals_management: "goals_management",
signals.labels_management: "labels_management",
signals.suggestions_management: "suggestions_management",
signals.help_management: "help_management",
signals.jsfiddle_management: "jsfiddle_management",
Expand Down Expand Up @@ -159,6 +161,15 @@ def record_event_goals_management(sender, performer, signal, content, **_):
).save()


@receiver(signals.labels_management, sender=EditLabels)
def record_event_labels_management(sender, performer, signal, content, **_):
Event(
performer=performer,
type=types[signal],
content=content,
).save()


@receiver(signals.help_management, sender=ChangeHelp)
def record_event_help_management(sender, performer, signal, content, **_):
Event(
Expand Down
23 changes: 23 additions & 0 deletions zds/tutorialv2/models/labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.db import models


class Label(models.Model):
"""
This model represents the labels used to highlight the quality of publications.
Here few example of labels: "well-written", "comprehensive", "well-researched", etc.
"""

class Meta:
verbose_name = "Label"
verbose_name_plural = "Labels"

name = models.CharField("Nom", max_length=80, help_text="Nom du label")
description = models.TextField("Description", blank=True, help_text="Description du label")
slug = models.SlugField(
max_length=80,
unique=True,
help_text="L'URL pour voir les contenus associés au label est de la forme contenus/labels/slug",
)

def __str__(self):
return self.name
4 changes: 4 additions & 0 deletions zds/tutorialv2/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
# For the signal below, the arguments "performer" and "content" shall be provided.
goals_management = Signal()

# Labels management
# For the signal below, the arguments "performer" and "content" shall be provided.
labels_management = Signal()

# Help management
# For the signal below, the arguments "performer" and "content" shall be provided.
help_management = Signal()
Expand Down
10 changes: 10 additions & 0 deletions zds/tutorialv2/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from zds.tutorialv2.models.versioned import Container, Extract
from zds.tutorialv2.publication_utils import publish_content
from zds.tutorialv2.utils import init_new_repo
from zds.tutorialv2.models.labels import Label

text_content = "Ceci est un texte bidon, **avec markown**"

Expand Down Expand Up @@ -321,3 +322,12 @@ class Meta:
model = ContentContributionRole

title = factory.Sequence("Rôle {}".format)


class LabelFactory(factory.django.DjangoModelFactory):
class Meta:
model = Label

name = factory.Sequence("Mon label n°{}".format)
description = factory.Sequence("Très belle description n°{}".format)
slug = factory.Sequence("mon-label-{}".format)
Loading

0 comments on commit e3da299

Please sign in to comment.