Skip to content

Commit

Permalink
Ajout d’une page "Plan du site" (#279)
Browse files Browse the repository at this point in the history
* First version

* Fix tests

* Update translations

* Fix XML sitemap URL

* Don't lazy load translations in URLS
  • Loading branch information
Ash-Crow authored Mar 5, 2025
1 parent ddd3233 commit 9d0713c
Show file tree
Hide file tree
Showing 17 changed files with 204 additions and 53 deletions.
5 changes: 1 addition & 4 deletions config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
from proconnect import urls as oidc_urls

urlpatterns = [
path(
"sitemap.xml",
sitemap,
),
path("sitemap.xml", sitemap, name="xml_sitemap"),
path(settings.WAGTAILADMIN_PATH, include(wagtailadmin_urls)),
path("documents/", include(wagtaildocs_urls)),
path("api/v2/", api_router.urls),
Expand Down
Binary file modified content_manager/locale/fr/LC_MESSAGES/django.mo
Binary file not shown.
26 changes: 20 additions & 6 deletions content_manager/locale/fr/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-11 17:45+0100\n"
"PO-Revision-Date: 2025-02-11 18:22+0100\n"
"POT-Creation-Date: 2025-03-05 10:43+0100\n"
"PO-Revision-Date: 2025-03-05 10:47+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
Expand Down Expand Up @@ -595,7 +595,7 @@ msgstr "Informations de contact"
#: content_manager/models.py:136 content_manager/models.py:150
#: content_manager/models.py:156
#: content_manager/templates/content_manager/tags_list_page.html:49
#: content_manager/views.py:46 content_manager/views.py:77
#: content_manager/views.py:47 content_manager/views.py:78
msgid "Tags"
msgstr "Étiquettes"

Expand Down Expand Up @@ -1311,6 +1311,7 @@ msgstr "Aucun article trouvé."
msgid "See all posts"
msgstr "Voir tous les articles"

#: content_manager/templates/content_manager/blocks/button.html:6
#: content_manager/templates/content_manager/blocks/card_horizontal.html:11
#: content_manager/templates/content_manager/blocks/card_vertical.html:11
#: content_manager/templates/content_manager/blocks/contact_card_vertical.html:14
Expand Down Expand Up @@ -1359,6 +1360,10 @@ msgstr "Visibilité de la page restreinte par mot de passe"
msgid "Page with restricted visibility"
msgstr "Visibilité de la page restreinte"

#: content_manager/templates/content_manager/blocks/sitemap_entry.html:2
msgid "Restricted access"
msgstr "Accès restreint"

#: content_manager/templates/content_manager/blocks/stepper.html:8
#, python-format
msgid "Step %(current_step)s of %(total_steps)s"
Expand Down Expand Up @@ -1402,6 +1407,11 @@ msgstr "Afficher"
msgid "Continue"
msgstr "Continuer"

#: content_manager/templates/content_manager/sitemap_page.html:18
#: content_manager/views.py:101
msgid "Sitemap"
msgstr "Plan du site"

#: content_manager/templates/content_manager/widgets/dsfr-icon-picker-widget.html:9
msgid "Select icon"
msgstr "Sélectionner une icône"
Expand All @@ -1410,16 +1420,20 @@ msgstr "Sélectionner une icône"
msgid "search/"
msgstr "recherche/"

#: content_manager/views.py:52
#: content_manager/urls.py:9
msgid "sitemap/"
msgstr "plan-du-site/"

#: content_manager/views.py:53
msgid "List of all the tags."
msgstr "Liste de toutes les étiquettes."

#: content_manager/views.py:73
#: content_manager/views.py:74
#, python-brace-format
msgid "Pages tagged with {tag}"
msgstr "Pages avec l’étiquette {tag}"

#: content_manager/views.py:82
#: content_manager/views.py:83
#, python-brace-format
msgid "List of pages tagged with {tag}"
msgstr "Liste de pages avec l’étiquette {tag}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% load wagtailcore_tags i18n %}
{% translate "Restricted access" as restricted_access_label %}
{% for subpage in pagelist.get_children.live %}
{% if not subpage.get_view_restrictions or user.is_authenticated %}
<li>
{% if subpage.get_view_restrictions %}
<span class="fr-icon-lock-line"
aria-hidden="true"
title="{{ restricted_access_label }}"></span>
{% endif %}
<a href="{% pageurl subpage %}">{{ subpage.title }}</a>
{% if subpage.get_view_restrictions %}<span class="fr-sr-only">({{ restricted_access_label }})</span>{% endif %}
{% if subpage.get_children.count > 0 %}
<ul>
{% include "content_manager/blocks/sitemap_entry.html" with pagelist=subpage %}
</ul>
{% endif %}
</li>
{% endif %}
{% endfor %}
33 changes: 33 additions & 0 deletions content_manager/templates/content_manager/sitemap_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{% extends "base.html" %}

{% load static dsfr_tags wagtailcore_tags wagtailimages_tags i18n %}

{% block title %}
<title>{{ title }} — {{ settings.content_manager.CmsDsfrConfig.site_title }}</title>
{% endblock title %}

{% block description %}
<meta name="description" content="{{ home_page.search_description }}" />
{% endblock description %}

{% block content %}
{% include "content_manager/blocks/messages.html" %}

<div class="fr-container fr-mt-6w">
{% dsfr_breadcrumb breadcrumb %}
<h1>{% translate "Sitemap" %}</h1>
</div>

<div class="fr-container fr-mt-6w">
<div class="fr-grid-row fr-grid-row--gutters fr-mb-3w">
<ul>
<li>
<a href="{% pageurl home_page %}">{{ home_page.title }}</a>
<ul>
{% include "content_manager/blocks/sitemap_entry.html" with pagelist=home_page %}
</ul>
</li>
</ul>
</div>
</div>
{% endblock content %}
60 changes: 51 additions & 9 deletions content_manager/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,84 @@
from django.contrib.auth import get_user_model
from django.core.management import call_command
from django.urls import reverse
from wagtail.models import Page
from wagtail.rich_text import RichText
from wagtail.test.utils import WagtailPageTestCase
from wagtailmenus.models.menuitems import FlatMenuItem, MainMenuItem
from wagtailmenus.models.menus import FlatMenu, MainMenu

from content_manager.models import CatalogIndexPage, CmsDsfrConfig, ContentPage, MegaMenu, MegaMenuCategory
from content_manager.services.accessors import get_or_create_content_page
from content_manager.utils import get_default_site

User = get_user_model()


class ContentPageTestCase(WagtailPageTestCase):
def setUp(self):
home = Page.objects.get(slug="home")
home_page = Page.objects.get(slug="home")
self.admin = User.objects.create_superuser("test", "[email protected]", "pass")
self.admin.save()
self.content_page = home.add_child(
self.public_content_page = home_page.add_child(
instance=ContentPage(
title="Page de contenu",
slug="content-page",
title="Page de contenu publique",
slug="public-content-page",
owner=self.admin,
)
)
self.content_page.save()
self.public_content_page.save()
self.private_content_page = get_or_create_content_page(
"private-content-page",
title="Page de contenu privée",
body=[("subpageslist", None)],
parent_page=home_page,
restriction_type="login",
)
self.private_content_page.save()

def test_content_page_is_renderable(self):
self.assertPageIsRenderable(self.content_page)
self.assertPageIsRenderable(self.public_content_page)

def test_content_page_has_minimal_content(self):
url = self.content_page.url
response = self.client.get(url)
response = self.client.get(self.public_content_page.url)
self.assertEqual(response.status_code, 200)

self.assertContains(
response,
"<title>Page de contenu — Titre du site</title>",
"<title>Page de contenu publique — Titre du site</title>",
)

def test_public_content_page_is_in_the_site_map(self):
url = reverse("readable_sitemap")
response = self.client.get(url)

self.assertContains(
response,
"""<a href="/public-content-page/">Page de contenu publique</a>""",
)

def test_private_content_page_is_not_rendered_when_logged_out(self):
response = self.client.get(self.private_content_page.url)

self.assertEqual(response.status_code, 302)

def test_private_content_page_is_not_in_the_site_map_when_logged_out(self):
url = reverse("readable_sitemap")
response = self.client.get(url)

self.assertNotContains(
response,
"""<a href="/private-content-page/">Page de contenu privée</a>""",
)

def test_private_content_page_is_in_the_site_map_when_logged_in(self):
self.client.login(username="test", password="pass")
url = reverse("readable_sitemap")
response = self.client.get(url)

self.assertContains(
response,
"""<a href="/private-content-page/">Page de contenu privée</a>""",
)


Expand Down
5 changes: 3 additions & 2 deletions content_manager/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from django.urls import include, path
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext as _
from wagtail import urls as wagtail_urls

from content_manager.views import SearchResultsView, TagsListView, TagView
from content_manager.views import SearchResultsView, SiteMapView, TagsListView, TagView

urlpatterns = [
path(_("search/"), SearchResultsView.as_view(), name="cms_search"),
path(_("sitemap/"), SiteMapView.as_view(), name="readable_sitemap"),
path("tags/<str:tag>/", TagView.as_view(), name="global_tag"),
path("tags/", TagsListView.as_view(), name="global_tags_list"),
path("", include(wagtail_urls)),
Expand Down
24 changes: 24 additions & 0 deletions content_manager/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.utils.translation import gettext_lazy as _
from django.views.generic import ListView, TemplateView
from unidecode import unidecode
from wagtail.models import Site

from content_manager.models import ContentPage, Tag

Expand Down Expand Up @@ -82,3 +83,26 @@ def get_context_data(self, **kwargs):
context["search_description"] = _("List of pages tagged with {tag}").format(tag=tag.name)

return context


class SiteMapView(TemplateView):
"""
Readable sitemap for accessibility
(different than the SEO-oriented sitemap.xml)
"""

template_name = "content_manager/sitemap_page.html"

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
site = Site.find_for_request(self.request)
context["home_page"] = site.root_page

title = _("Sitemap")
context["title"] = title

context["breadcrumb"] = {
"links": [],
"current": title,
}
return context
Binary file modified dashboard/locale/fr/LC_MESSAGES/django.mo
Binary file not shown.
32 changes: 16 additions & 16 deletions dashboard/locale/fr/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-05 15:33+0100\n"
"PO-Revision-Date: 2025-02-05 15:34+0100\n"
"POT-Creation-Date: 2025-03-05 10:43+0100\n"
"PO-Revision-Date: 2025-03-05 10:48+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: fr\n"
Expand Down Expand Up @@ -72,65 +72,65 @@ msgstr "Réinitialisez votre mot de passe"
msgid "Connection"
msgstr "Connexion"

#: dashboard/templates/wagtailadmin/login.html:13
#: dashboard/templates/wagtailadmin/login.html:15
msgid "Login with"
msgstr "S’identifier avec"

#: dashboard/templates/wagtailadmin/login.html:16
#: dashboard/templates/wagtailadmin/login.html:18
msgid "What is ProConnect?"
msgstr "Qu’est-ce que ProConnect ?"

#: dashboard/templates/wagtailadmin/login.html:17
#: dashboard/templates/wagtailadmin/login.html:19
msgid "Opens a new window"
msgstr "Ouvre une nouvelle fenêtre"

#: dashboard/templates/wagtailadmin/login.html:31
#: dashboard/templates/wagtailadmin/login.html:33
msgid "Log in with your account"
msgstr "Se connecter avec son compte"

#: dashboard/templates/wagtailadmin/login.html:34
#: dashboard/templates/wagtailadmin/login.html:36
msgid "Unless otherwise stated, all fields are mandatory."
msgstr "Sauf mention contraire, tous les champs sont obligatoires."

#: dashboard/templates/wagtailadmin/login.html:40
#: dashboard/templates/wagtailadmin/login.html:42
msgid "Error: Your username and password do not match, please try again."
msgstr ""
"Erreur : Votre identifiant et mot de passe ne correspondent pas, merci de "
"réessayer."

#: dashboard/templates/wagtailadmin/login.html:47
#: dashboard/templates/wagtailadmin/login.html:49
msgid ""
"Error: Your account does not have access to this page. To continue, please "
"log in with an authorized account."
msgstr ""
"Erreur : Votre compte n’a pas accès à cette page. Pour continuer, merci de "
"vous connecter avec un compte autorisé."

#: dashboard/templates/wagtailadmin/login.html:60
#: dashboard/templates/wagtailadmin/login.html:62
msgid "Username:"
msgstr "Identifiant :"

#: dashboard/templates/wagtailadmin/login.html:66
#: dashboard/templates/wagtailadmin/login.html:68
msgid "Password:"
msgstr "Mot de passe :"

#: dashboard/templates/wagtailadmin/login.html:69
#: dashboard/templates/wagtailadmin/login.html:71
msgid "Show password"
msgstr "Afficher le mot de passe"

#: dashboard/templates/wagtailadmin/login.html:74
#: dashboard/templates/wagtailadmin/login.html:76
msgid "Show"
msgstr "Afficher"

#: dashboard/templates/wagtailadmin/login.html:80
#: dashboard/templates/wagtailadmin/login.html:82
msgid "Forgotten password?"
msgstr "Mot de passe oublié ?"

#: dashboard/templates/wagtailadmin/login.html:88
#: dashboard/templates/wagtailadmin/login.html:90
msgid "Remember me"
msgstr "Se souvenir de moi"

#: dashboard/templates/wagtailadmin/login.html:95
#: dashboard/templates/wagtailadmin/login.html:97
msgid "Connect"
msgstr "Se connecter"

Expand Down
Binary file modified locale/fr/LC_MESSAGES/django.mo
Binary file not shown.
Loading

0 comments on commit 9d0713c

Please sign in to comment.