Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Ajout d'un sitemap #1450

Merged
merged 7 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.sitemaps",
"django.contrib.sites",
"django.contrib.flatpages",
"django.contrib.gis",
Expand Down
3 changes: 3 additions & 0 deletions config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.urls import include, path
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.contrib.sitemaps.views import sitemap
from wagtail.documents import urls as wagtaildocs_urls
from wagtail_transfer import urls as wagtailtransfer_urls

Expand All @@ -20,6 +21,8 @@
path("profil/reseaux/", include("lemarche.www.dashboard_networks.urls")),
path("profil/listes-dachats/", include("lemarche.www.dashboard_favorites.urls")),
path("select2/", include("django_select2.urls")),
# sitemap
path("sitemap.xml", sitemap, name="sitemap"), # appears above the default Wagtail page serving route
# admin blog
path("cms/", include(wagtailadmin_urls)),
path("blog/", include("blog.urls")),
Expand Down
3 changes: 3 additions & 0 deletions lemarche/templates/layouts/_footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ <h3 class="fr-footer__top-cat">En savoir plus</h3>
</div>
<div class="fr-footer__bottom">
<ul class="fr-footer__bottom-list">
<li class="fr-footer__bottom-item">
<a class="fr-footer__bottom-link" href="{% url 'pages:plan-du-site' %}">Plan du site</a>
</li>
<li class="fr-footer__bottom-item">
<a class="fr-footer__bottom-link" href="{% url 'pages:accessibilite' %}">Accessibilité : non conforme</a>
</li>
Expand Down
19 changes: 19 additions & 0 deletions lemarche/templates/pages/plan_du_site.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% extends "layouts/base.html" %}
{% load dsfr_tags process_dict static %}

{% block page_title %}Plan du site{{ block.super }}{% endblock page_title %}

{% block content %}
<section class="fr-my-6v">
<div class="fr-container">
<h1>Plan du site</h1>
<ul>
{% for item in sitemap_urls %}
<li style="margin-left: {{ item.depth|add:1 }}em;">
<a href="{{ item.url }}">{{ item.title }}</a>
</li>
{% endfor %}
</ul>
</div>
</section>
{% endblock content %}
76 changes: 76 additions & 0 deletions lemarche/www/pages/tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import xml.etree.ElementTree as ET

from django.test import TestCase
from django.urls import reverse
from django.utils import timezone
from wagtail.models import Page as WagtailPage, Site

from lemarche.siaes.factories import SiaeFactory
from lemarche.users.factories import UserFactory
Expand Down Expand Up @@ -133,3 +137,75 @@ def test_buyer_user_home(self):

self.assertContains(response, "Déconnexion")
self.assertContains(response, reverse("auth:logout"))


class SitemapTests(TestCase):
@classmethod
def setUpTestData(cls):
# WagtailPage creation for tests
root = WagtailPage.get_first_root_node()
Site.objects.create(
hostname="testserver",
root_page=root,
is_default_site=True,
site_name="testserver",
)
cls.wagtail_page = root.add_child(
instance=WagtailPage(
title="Test WagtailPage",
slug="test-wagtail-page",
depth=2,
path="0002",
last_published_at=timezone.now(),
)
)

def test_sitemap_xml(self):
"""Test sitemap.xml exists"""
response = self.client.get(reverse("sitemap"))

self.assertEqual(response.status_code, 200)

def test_sitemap_xml_is_not_empty(self):
"""Test sitemap is not empty and contains urls"""
response = self.client.get(reverse("sitemap"))

self.assertGreater(len(response.content), 0)

def test_sitemap_is_valid_xml(self):
"""Test sitemap is valid XML"""
response = self.client.get(reverse("sitemap"))

try:
ET.fromstring(response.content)
except ET.ParseError:
self.fail("Le sitemap n'est pas dans un format XML valide.")

def test_sitemap_xml_contains_wagtail_page(self):
"""Test the sitemap contains the wagtail page URL."""
response = self.client.get(reverse("sitemap"))
wagtail_page_url = self.wagtail_page.full_url

self.assertEqual(response.status_code, 200)
self.assertContains(response, f"<loc>{wagtail_page_url}</loc>")

def test_wagtail_page_contains_lastmod_tag(self):
"""Test the sitemap contains the lastmod tag for the wagtail page."""
response = self.client.get(reverse("sitemap"))
lastmod = self.wagtail_page.last_published_at.strftime("%Y-%m-%d")

self.assertContains(response, f"<lastmod>{lastmod}</lastmod>")

def test_sitemap_html(self):
"""Test that the HTML sitemap page is accessible"""
response = self.client.get("/plan-du-site/")
self.assertEqual(response.status_code, 200)

def test_sitemap_html_contains_wagtail_page(self):
"""Test that the HTML sitemap contains the wagtail page URL and title"""
response = self.client.get("/plan-du-site/")
wagtail_page_url = self.wagtail_page.get_full_url()
wagtail_page_title = self.wagtail_page.title

self.assertContains(response, f'href="{wagtail_page_url}"')
self.assertContains(response, wagtail_page_title)
2 changes: 2 additions & 0 deletions lemarche/www/pages/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
ImpactCalculatorView,
PageView,
SiaeGroupListView,
SitemapView,
SocialImpactBuyersCalculatorView,
StatsView,
TrackView,
Expand Down Expand Up @@ -83,6 +84,7 @@
path("cgu/", PageView.as_view(), {"url": "/cgu/"}, name="cgu"),
path("cgu-api/", PageView.as_view(), {"url": "/cgu-api/"}, name="cgu-api"),
path("confidentialite/", PageView.as_view(), {"url": "/confidentialite/"}, name="confidentialite"),
path("plan-du-site/", SitemapView.as_view(), name="plan-du-site"),
# Error pages
path("403/", TemplateView.as_view(template_name="403.html"), name="403"),
path("404/", TemplateView.as_view(template_name="404.html"), name="404"),
Expand Down
20 changes: 20 additions & 0 deletions lemarche/www/pages/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
from lemarche.www.tenders.utils import create_tender_from_dict, get_or_create_user_from_anonymous_content
from lemarche.www.tenders.views import TenderCreateMultiStepView

from wagtail.models import Site as WagtailSite


class HomeView(TemplateView):
template_name = "pages/home.html"
Expand Down Expand Up @@ -393,3 +395,21 @@ def trigger_error(request):
if request.POST:
raise Exception("%s error: %s" % (request.POST.get("status_code"), request.POST.get("error_message")))
print(1 / 0) # Should raise a ZeroDivisionError.


class SitemapView(View):
def get(self, request):
# Récupérer la page d'accueil
site = WagtailSite.find_for_request(request)
homepage = site.root_page # Page d'accueil de Wagtail

# Récupérer toutes les pages descendantes publiées
all_pages = homepage.get_descendants(inclusive=True).live()

# Construire une liste des URLs et titres
urls_with_titles = [
{"url": page.get_full_url(request=request), "title": page.title, "depth": page.depth - homepage.depth}
for page in all_pages
]

return render(request, "pages/plan_du_site.html", {"sitemap_urls": urls_with_titles})
Loading