Skip to content

Commit a3ddc68

Browse files
committed
feat(a11y): add sitemap page satisfying RGAA 12.1 requirement
RGAA 12.1 requires two navigation systems; we had a header nav but no sitemap (the footer link was a dead `href="#"`). This adds: - `config/sitemap.yml` — authoritative source of all public pages for both API Entreprise and API Particulier, structured by section with explicit titles. Paths are stored directly (no dependency on i18n page_title keys). - `/plan-du-site` route + `pages#sitemap` action in both namespaces. - `shared/pages/sitemap.html.erb` — shared view rendering sections from the YAML assigned by the controller. - Footer links updated from `href="#"` to the real path helper. - `spec/sitemap_spec.rb` — validates every path in the YAML resolves to a real GET route (using the domain-constrained host), so pages cannot be added to the sitemap without a matching route and vice versa. Closes [API-6732](https://linear.app/datagouv/issue/API-6732)
1 parent 538b030 commit a3ddc68

9 files changed

Lines changed: 132 additions & 2 deletions

File tree

site/app/controllers/api_entreprise/pages_controller.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ def accessibility
3131
render 'shared/pages/accessibility'
3232
end
3333

34+
def sitemap
35+
@sitemap_sections = YAML.load_file(Rails.root.join('config/sitemap.yml'))['api_entreprise']
36+
render 'shared/pages/sitemap'
37+
end
38+
3439
def redoc
3540
render 'shared/pages/redoc'
3641
end

site/app/controllers/api_particulier/pages_controller.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ def accessibility
4747
render 'shared/pages/accessibility'
4848
end
4949

50+
def sitemap
51+
@sitemap_sections = YAML.load_file(Rails.root.join('config/sitemap.yml'))['api_particulier']
52+
render 'shared/pages/sitemap'
53+
end
54+
5055
private
5156

5257
def page_layout

site/app/views/shared/api_entreprise/_footer.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<div class="fr-footer__bottom">
2828
<ul class="fr-footer__bottom-list">
2929
<li class="fr-footer__bottom-item">
30-
<a class="fr-footer__bottom-link" href="#">Plan du site</a>
30+
<a class="fr-footer__bottom-link" href="<%= sitemap_path %>">Plan du site</a>
3131
</li>
3232
<li class="fr-footer__bottom-item">
3333
<a class="fr-footer__bottom-link" href="<%= accessibilite_path %>">Accessibilité: non conforme</a>

site/app/views/shared/api_particulier/_footer.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<div class="fr-footer__bottom">
2828
<ul class="fr-footer__bottom-list">
2929
<li class="fr-footer__bottom-item">
30-
<a class="fr-footer__bottom-link" href="#">Plan du site</a>
30+
<a class="fr-footer__bottom-link" href="<%= api_particulier_sitemap_path %>">Plan du site</a>
3131
</li>
3232
<li class="fr-footer__bottom-item">
3333
<a class="fr-footer__bottom-link" href="<%= accessibilite_path %>">Accessibilité: non conforme</a>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<h1>Plan du site</h1>
2+
3+
<% @sitemap_sections.each do |section| %>
4+
<section>
5+
<h2><%= section['section'] %></h2>
6+
<ul>
7+
<% section['pages'].each do |page| %>
8+
<li>
9+
<a href="<%= page['path'] %>"><%= page['title'] %></a>
10+
</li>
11+
<% end %>
12+
</ul>
13+
</section>
14+
<% end %>

site/config/routes/api_entreprise.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,6 @@
8181
get '/cgu', to: 'pages#cgu', as: :cgu
8282
get '/donnees_personnelles', to: 'pages#donnees_personnelles', as: :donnees_personnelles
8383
get '/accessibilite', to: 'pages#accessibility', as: :accessibilite
84+
get '/plan-du-site', to: 'pages#sitemap', as: :sitemap
8485
end
8586
end

site/config/routes/api_particulier.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
get '/cgu', to: 'pages#cgu', as: :cgu
8383
get '/donnees_personnelles', to: 'pages#donnees_personnelles', as: :donnees_personnelles
8484
get '/accessibilite', to: 'pages#accessibility', as: :accessibilite
85+
get '/plan-du-site', to: 'pages#sitemap', as: :sitemap
8586

8687
get '/datapass', to: 'reporters#index', as: :dashboard_reporter
8788
end

site/config/sitemap.yml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
api_entreprise:
2+
- section: Découvrir
3+
pages:
4+
- path: /
5+
title: Accueil
6+
- path: /catalogue
7+
title: Catalogue des API
8+
- path: /cas_usages
9+
title: Cas d'usages
10+
- path: /faq
11+
title: FAQ & contact
12+
- path: /nouveautes
13+
title: Nouveautés
14+
- path: /developpeurs
15+
title: Espace développeur
16+
- path: /apis/status
17+
title: Statut des API
18+
- path: /infolettre
19+
title: Lettre d'information
20+
- path: /stats
21+
title: Statistiques
22+
- section: Mon espace
23+
pages:
24+
- path: /compte/se-connecter
25+
title: Se connecter
26+
- section: Informations légales
27+
pages:
28+
- path: /accessibilite
29+
title: Accessibilité
30+
- path: /cgu
31+
title: Conditions générales d'utilisation
32+
- path: /mentions-legales
33+
title: Mentions légales
34+
- path: /donnees_personnelles
35+
title: Données personnelles
36+
- path: /plan-du-site
37+
title: Plan du site
38+
39+
api_particulier:
40+
- section: Découvrir
41+
pages:
42+
- path: /
43+
title: Accueil
44+
- path: /catalogue
45+
title: Catalogue des API
46+
- path: /cas_usages
47+
title: Cas d'usages & modalités d'appel
48+
- path: /faq
49+
title: FAQ & contact
50+
- path: /nouveautes
51+
title: Nouveautés
52+
- path: /developpeurs
53+
title: Espace développeur
54+
- path: /status/apis
55+
title: Statut des API
56+
- path: /infolettre
57+
title: Lettre d'information
58+
- path: /stats
59+
title: Statistiques
60+
- section: Mon espace
61+
pages:
62+
- path: /compte/se-connecter
63+
title: Se connecter
64+
- section: Informations légales
65+
pages:
66+
- path: /accessibilite
67+
title: Accessibilité
68+
- path: /cgu
69+
title: Conditions générales d'utilisation
70+
- path: /mentions-legales
71+
title: Mentions légales
72+
- path: /donnees_personnelles
73+
title: Données personnelles
74+
- path: /plan-du-site
75+
title: Plan du site

site/spec/sitemap_spec.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe 'sitemap.yml' do # rubocop:disable RSpec/DescribeClass
6+
let(:sitemap) { YAML.load_file(Rails.root.join('config/sitemap.yml')) }
7+
8+
hosts = {
9+
'api_entreprise' => 'entreprise.api.localtest.me',
10+
'api_particulier' => 'particulier.api.localtest.me'
11+
}
12+
13+
hosts.each do |ns, host|
14+
describe ns do
15+
it 'every path is a valid GET route' do
16+
invalid = sitemap.fetch(ns).flat_map { |section| section['pages'] }.filter_map do |page|
17+
url = "http://#{host}#{page['path']}"
18+
Rails.application.routes.recognize_path(url, method: :get)
19+
nil
20+
rescue ActionController::RoutingError
21+
page['path']
22+
end
23+
24+
expect(invalid).to be_empty,
25+
"Unknown routes in config/sitemap.yml [#{ns}]:\n#{invalid.map { |p| " #{p}" }.join("\n")}"
26+
end
27+
end
28+
end
29+
end

0 commit comments

Comments
 (0)