Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0bf16b1
fix(a11y): cas d'usage — picto alt vide, label sémantique, lien exter…
Samuelfaure Jun 30, 2026
9c3ac25
fix(a11y): FAQ — bouton DSFR sidemenu manquant sur mobile (API-6738)
Samuelfaure Jun 30, 2026
2ceaa12
fix(a11y): catalogue — alt vide sur logos fournisseurs (RGAA 1.2) (AP…
Samuelfaure Jun 30, 2026
05d43cd
fix(a11y): endpoint show — HTML valide, aria-label nav, alt logos (AP…
Samuelfaure Jun 30, 2026
910103f
Fix ActionView::SyntaxErrorInTemplate caused by curly quotes
Samuelfaure Jun 30, 2026
a5f734d
fix(a11y): layouts admin/editor/provider — main, skip links, titre (N…
Samuelfaure Jun 30, 2026
bfa1bf0
fix(a11y): layouts AE/AP — skip links, landmark <main>, content_for :…
Samuelfaure Jun 30, 2026
df191b3
fix(a11y): images décoratives, loader, impersonate, section accès (NC…
Samuelfaure Jun 30, 2026
9aaac3b
fix(a11y): liens nouvelle fenêtre — navigation, footer, home (NC 13.2)
Samuelfaure Jun 30, 2026
0e80946
fix(a11y): endpoints — lien vide, aria-live, titres page, alt, liens …
Samuelfaure Jun 30, 2026
e11c07f
fix(a11y): token views — scopes accordion, icônes, DataPass, titres (…
Samuelfaure Jun 30, 2026
518495a
fix(a11y): wizard, sessions, habilitations — h1, tableau, couleur sta…
Samuelfaure Jun 30, 2026
d70fb3e
fix(a11y): titres de page, cas d'usages — liens, liste, tableau (NC 5…
Samuelfaure Jun 30, 2026
ee206ed
fix(a11y): add title attribute to newsletter iframe
skelz0r Jun 18, 2026
f3ccc09
fix(a11y): fix invalid ul nested inside p on accessibility page
skelz0r Jun 18, 2026
daf67f6
fix(a11y): fix alt text on home page partner logos and decorative pictos
skelz0r Jun 18, 2026
2cdaa4b
fix(a11y): signal new-window links via external_link_to helper
skelz0r Jun 18, 2026
59462e6
fix(a11y): fix mailto links — missing prefix and uninformative labels…
skelz0r Jun 18, 2026
b13bc8c
fix(a11y): fix heading hierarchy on home page sections (RGAA 9.1)
skelz0r Jun 18, 2026
9d1aca5
fix(a11y): add lang="en" on English words, replace "newsletter" (RGAA…
skelz0r Jun 18, 2026
07eae3f
fix(a11y): add skip link, main landmark and role=banner to both layouts
skelz0r Jun 18, 2026
09d7fe6
feat(a11y): dynamic <title> per page (RGAA 8.5/8.6)
skelz0r Jun 18, 2026
0541b0f
fix: @cas_usage.name -> @fiche_pratique.name in cas_usages show views
Samuelfaure Jul 1, 2026
88c7fb9
fix: rubocop RSpec/ContextWording in layout landmark specs
Samuelfaure Jul 1, 2026
7060840
fix(a11y): missing page_title i18n keys — authorization_requests, blo…
Samuelfaure Jul 1, 2026
e6db9e0
fix(a11y): provider alt text regression, unify sr-only new-window lab…
Samuelfaure Jul 1, 2026
5e8696a
fix: external_link_to block form drops html_options, admin layout mis…
Samuelfaure Jul 1, 2026
b754ca3
fix(spec): update landmark specs to match layout id='contenu'
Samuelfaure Jul 1, 2026
5bcc2ac
fix(a11y): dedupe main landmark, fix skip-link focus in Firefox/Safari
Samuelfaure Jul 3, 2026
9a6dea1
fix(a11y): rename authorization_requests index page title to match H1…
Samuelfaure Jul 6, 2026
cf92247
fix(a11y): forward block through auto_link so new-window label render…
Samuelfaure Jul 6, 2026
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
39 changes: 37 additions & 2 deletions site/app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
require 'kramdown-parser-gfm'

module ApplicationHelper
def auto_link(text, options = {})
Anchored::Linker.auto_link(text, options)
def auto_link(text, options = {}, &)
Anchored::Linker.auto_link(text, options, &)
end

def status_to_color(status)
Expand Down Expand Up @@ -36,6 +36,32 @@ def boolean_i18n(value)
I18n.t(i18n_key)
end

def external_link_to(name = nil, href = nil, html_options = {}, &)
if block_given?
html_options = href if href.is_a?(Hash)
href = name
end

html_options = html_options.merge(target: '_blank', rel: 'noopener noreferrer')
sr_label = content_tag(:span, '(nouvelle fenêtre)', class: 'fr-sr-only')

if block_given?
link_to(href, html_options) do
concat(capture(&))
concat(sr_label)
end
else
link_to(safe_join([name, sr_label]), href, html_options)
end
end

def full_page_title
namespace = controller_path.split('/').first
site_name = t("layouts.#{namespace}.application.title")
title = content_for?(:page_title) ? content_for(:page_title) : static_page_title
title.present? ? "#{title} — #{site_name}" : site_name
end

def icon(kind)
"<span class=\"icon #{kind}\" aria-hidden=\"true\"></span>".html_safe
end
Expand All @@ -47,4 +73,13 @@ def api_name
def support_email
t("#{namespace}.support_email")
end

private

def static_page_title
key = "#{controller_path.tr('/', '.')}.#{action_name}.page_title"
return t(key).presence if I18n.exists?(key)

raise "Missing page title for '#{key}'. Use content_for(:page_title) or add the i18n key." if Rails.env.local?
end
end
4 changes: 4 additions & 0 deletions site/app/models/abstract_blog_post.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ class AbstractBlogPost

attr_accessor :id, :content

def title
content.lines.find { |l| l.start_with?('# ') }&.delete_prefix('# ')&.strip
end

def self.find(id)
file = Rails.root.join('config/blog_posts', api, "#{id}.md")

Expand Down
1 change: 1 addition & 0 deletions site/app/views/api_entreprise/cas_usages/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<% content_for :title, t('.title') %>
<div id="cas-usages" class="fr-container--fluid">
<div class="banner fr-pt-5w fr-pb-8w">
<div class="fr-container">
Expand Down
1 change: 1 addition & 0 deletions site/app/views/api_entreprise/cas_usages/show.html.erb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
<% content_for :page_title, @fiche_pratique.name %>
<%= render partial: 'shared/cas_usages/show', locals: { api: 'api_entreprise' } %>
26 changes: 14 additions & 12 deletions site/app/views/api_entreprise/endpoints/_details.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,31 @@
<%= t('.format.title') %>
</h3>

<% @endpoint.format.each do |format| %>
<div>
<%= format %>
</div>
<% end %>
<ul>
<% @endpoint.format.each do |format| %>
<li><%= format %></li>
<% end %>
</ul>

<h3 class="fr-h6 fr-pt-2w fr-mb-1v">
<%= t('.parameters.title', count: @endpoint.parameters.count) %>
</h3>

<% @endpoint.parameters.each do |parameter| %>
<div>
<%= parameter %>
</div>
<% end %>
<ul>
<% @endpoint.parameters.each do |parameter| %>
<li><%= parameter %></li>
<% end %>
</ul>

<h3 class="fr-h6 fr-pt-2w fr-mb-1v">
<%= t('.availability.title') %>
</h3>
<turbo-frame id="endpoint_status" src="<%= endpoint_status_path(uid: @endpoint.uid) %>">
<div class="fr-pb-1w" style="color: grey;">Loading...</div>
</turbo-frame>
<a class="fr-link" title="API Entreprise Status Page" href="https://status.entreprise.api.gouv.fr" target="_blank">
<a class="fr-link" title="API Entreprise Status Page" href="https://status.entreprise.api.gouv.fr" target="_blank" rel="noopener noreferrer">
<%= t('.availability.link') %>
<span class="fr-sr-only">(nouvelle fenêtre)</span>
</a>
<div class="fr-pt-1w">
<% if @endpoint.maintenances.present? %>
Expand Down Expand Up @@ -65,8 +66,9 @@

<%= link_to t('.technical_specifications.cta'), developers_openapi_path(anchor: @endpoint.redoc_anchor), data: { turbo: false }, class: %(fr-btn fr-btn--icon-right fr-icon-arrow-right-line) %>

<a href="<%= @endpoint.test_cases_external_url %>" target="_blank" class="fr-btn fr-btn--secondary fr-mt-2w">
<a href="<%= @endpoint.test_cases_external_url %>" target="_blank" rel="noopener noreferrer" class="fr-btn fr-btn--secondary fr-mt-2w">
<%= t('.test_cases') %>
<span class="fr-sr-only">(nouvelle fenêtre)</span>
</a>
<% end %>

Expand Down
2 changes: 1 addition & 1 deletion site/app/views/api_entreprise/endpoints/_endpoint.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<div class="fr-col-4">
<% endpoint.providers.each do |provider| %>
<%= image_tag(provider.image_path, class: %w(provider)) %>
<%= image_tag(provider.image_path, alt: "", class: %w(provider)) %>
<% end %>
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion site/app/views/api_entreprise/endpoints/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<% content_for :title, t('.title') %>
<div id="catalogue" class="fr-mb-1v" data-controller="search-catalogue">
<div class="banner-container">
<div class="fr-container">
Expand Down Expand Up @@ -41,7 +42,7 @@
<%= render @endpoints %>
</div>

<div class="fr-alert fr-alert--info fr-mt-4v" data-search-catalogue-target="noResults" style="display: none;">
<div class="fr-alert fr-alert--info fr-mt-4v" data-search-catalogue-target="noResults" aria-live="polite" aria-atomic="true" style="display: none;">
<p><%= t('.search.no_results') %></p>
</div>
</div>
Expand Down
77 changes: 36 additions & 41 deletions site/app/views/api_entreprise/endpoints/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<% content_for :page_title, @endpoint.title %>
<% layout_main_bloc = 8 %>
<article id="<%= dom_id(@endpoint) %>" class="endpoint">
<h1>
Expand All @@ -22,10 +23,9 @@
</p>
<p>
<%= t('.incoming.description') %>

<p class="fr-text--sm fr-mt-2w">
<%= t('.incoming.link_documentation').html_safe %> <%= link_to t('.incoming.cta'), developers_openapi_path(anchor: @endpoint.redoc_anchor), data: { turbo: false }, class: %() %>
</p>
</p>
<p class="fr-text--sm fr-mt-2w">
<%= t('.incoming.link_documentation').html_safe %> <%= link_to t('.incoming.cta'), developers_openapi_path(anchor: @endpoint.redoc_anchor), data: { turbo: false }, class: %() %>
</p>
</div>
<% elsif @endpoint.beta? %>
Expand All @@ -45,8 +45,8 @@
</p>


<nav class="" role="navigation">
<ul class="">
<nav aria-label="Sommaire de la page">
<ul>
<li>
<a class="fr-link fr-fi-arrow-down-line fr-link--icon-right" href="#perimetre">Périmètre de l'API</a>
</li>
Expand Down Expand Up @@ -76,7 +76,7 @@
<div class="fr-grid-row fr-grid-row--gutters fr-grid-row--middle">
<div class="fr-col-md-5 fr-col-12 logos">
<% @endpoint.providers.each do |provider| %>
<%= image_tag(provider.image_path, alt: 'Logo du fournisseur de données') %>
<%= image_tag(provider.image_path, alt: "Logo de #{provider.name}") %>
<% end %>
</div>

Expand Down Expand Up @@ -105,9 +105,9 @@
<% if @endpoint.alert.present? %>
<div class="fr-mt-4w fr-mb-4w">
<div class="fr-alert fr-alert--warning fr-mb-2w">
<h3 class="fr-alert__title">
<p class="fr-alert__title">
<%= raw @endpoint.alert['title'] %>
</h3>
</p>
<p>
<%= markdown_to_html(@endpoint.alert['description']) %>
</p>
Expand All @@ -124,15 +124,16 @@

<p>
<%= t('.deprecated.description') %>
<ul>
<% @endpoint.new_endpoints.each do |endpoint| %>
<li>
<%= link_to endpoint.title, endpoint_path(uid: endpoint.uid) %>
</li>
<% end %>
</ul>
<p class="fr-text--sm fr-mt-2w">
<%= t('.deprecated.link_documentation').html_safe %></p>
</p>
<ul>
<% @endpoint.new_endpoints.each do |endpoint| %>
<li>
<%= link_to endpoint.title, endpoint_path(uid: endpoint.uid) %>
</li>
<% end %>
</ul>
<p class="fr-text--sm fr-mt-2w">
<%= t('.deprecated.link_documentation').html_safe %>
</p>
</div>
<% end %>
Expand Down Expand Up @@ -360,30 +361,24 @@
</h3>

<p>
Cette API et l’utilisation de ses données est soumise aux CGU générales d’API Entreprise, dont voici les principaux éléments auxquels vous vous engagez :

<ul>
<li>
<strong>ne demander que les données strictement nécessaires</strong> ;
</li>
<li>
<strong>ne pas utiliser votre jeton d’accès pour une démarche différente</strong> de celle indiquée lors de votre demande (le cas échéant le jeton sera révoqué) ;
</li>
<li>
<strong>présenter les données obtenues uniquement aux seuls agents habilités</strong> et à tracer l’accès de ces agents aux données ;
</li>
<li>
<strong>ne pas commercialiser les données</strong> reçues et à ne pas les communiquer à des tiers en dehors des cas prévus par la loi.
</li>
</ul>

L’ensemble des conditions sont consultables et téléchargeables ci-dessous :

<br>
<br>

<%= link_to t('.cgu.cta'), cgu_path, id: 'cgu_link', class: %w(fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-eye-line), data: { turbo_frame: 'main-modal-content', 'fr-opened': 'false' }, 'aria-controls': 'main-modal' %>
Cette API et l'utilisation de ses données est soumise aux CGU générales d'API Entreprise, dont voici les principaux éléments auxquels vous vous engagez :
</p>
<ul>
<li>
<strong>ne demander que les données strictement nécessaires</strong> ;
</li>
<li>
<strong>ne pas utiliser votre jeton d'accès pour une démarche différente</strong> de celle indiquée lors de votre demande (le cas échéant le jeton sera révoqué) ;
</li>
<li>
<strong>présenter les données obtenues uniquement aux seuls agents habilités</strong> et à tracer l'accès de ces agents aux données ;
</li>
<li>
<strong>ne pas commercialiser les données</strong> reçues et à ne pas les communiquer à des tiers en dehors des cas prévus par la loi.
</li>
</ul>
<p>L'ensemble des conditions sont consultables et téléchargeables ci-dessous :</p>
<%= link_to t('.cgu.cta'), cgu_path, id: 'cgu_link', class: %w(fr-btn fr-btn--secondary fr-btn--icon-right fr-icon-eye-line fr-mt-2w), data: { turbo_frame: 'main-modal-content', 'fr-opened': 'false' }, 'aria-controls': 'main-modal' %>
<% end %>
</div>

Expand Down
3 changes: 3 additions & 0 deletions site/app/views/api_entreprise/faq/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
<div class="fr-col-12 fr-col-sm-4 fr-col-md-3">
<nav class="fr-sidemenu" aria-label="Menu latéral">
<div class="fr-sidemenu__inner">
<button class="fr-sidemenu__btn" hidden aria-controls="fr-sidemenu-wrapper" aria-expanded="false">
Catégories
</button>
<div class="fr-collapse" id="fr-sidemenu-wrapper">
<ul class="fr-sidemenu__list">
<% @faq_entries_grouped_by_categories.keys.each do |category_name| %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ Pourquoi traitons-nous des données à caractère personnel&nbsp;?
Vous disposez d’un droit d’accès et de rectification des données à caractère personnel qui vous concernent. Vous disposez également d’un droit d’opposition et de limitation du traitement de vos données.
</p>
<p class="fr-mt-2w fr-mb-2w">
Pour exercer vos droits ou pour toute question sur le traitement de vos données, vous pouvez nous écrire à l’adresse : <a href="support@entreprise.api.gouv.fr">support@entreprise.api.gouv.fr</a>
Pour exercer vos droits ou pour toute question sur le traitement de vos données, vous pouvez nous écrire à l’adresse : <a href="mailto:support@entreprise.api.gouv.fr" title="Envoyer un courriel au support">support@entreprise.api.gouv.fr</a>
</p>

<p class="fr-mt-2w fr-mb-2w">
Vous pouvez également contacter le délégué à la protection des données (DPD) des services du Premier Ministre par mail à <a href="dpd@pm.gouv.fr">dpd@pm.gouv.fr</a> ou par courrier à l'adresse suivante&nbsp;:<br/>
Vous pouvez également contacter le délégué à la protection des données (DPD) des services du Premier Ministre par mail à <a href="mailto:dpd@pm.gouv.fr" title="Envoyer un courriel au délégué à la protection des données">dpd@pm.gouv.fr</a> ou par courrier à l'adresse suivante&nbsp;:<br/>
Services du Premier Ministre<br/>
À l’attention du délégué à la protection des données (DPD)<br/>
56 rue de Varenne<br/>
Expand Down
1 change: 1 addition & 0 deletions site/app/views/api_entreprise/pages/home.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<% content_for :title, 'Accueil' %>
<div id="homepage">
<%= render 'shared/pages/home_alerts' %>
<%= render 'api_entreprise/pages/home/section_welcome' %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,31 @@
<%= t('.link_faq') %>&nbsp;<span class="" aria-hidden="true"></span>
<% end %>
<div class="info fr-mb-3w fr-mt-5w">
<%= image_tag("api_entreprise/home/pictos/donnees-certifiees.svg", class: %w(info--icon fr-icon--huge), alt: 'Pictogramme données certifiées') %>
<%= image_tag("api_entreprise/home/pictos/donnees-certifiees.svg", class: %w(info--icon fr-icon--huge), alt: '') %>
<div class="info--text">
<h3 class="fr-h6 fr-mb-1w"><%= t('.info_data_title') %></h3>
<p class="fr-text--alt fr-text--lg">
<%= t('.info_data_description') %></p>
</div>
</div>
<div class="info fr-mb-3w">
<%= image_tag("api_entreprise/home/pictos/fournisseur-donnees.svg", class: %w(info--icon fr-icon--huge), alt: 'Pictogramme fournisseurs de données regroupés') %>
<%= image_tag("api_entreprise/home/pictos/fournisseur-donnees.svg", class: %w(info--icon fr-icon--huge), alt: '') %>
<div class="info--text">
<h3 class="fr-h6 fr-mb-1w"><%= t('.info_provider_title') %></h3>
<p class="fr-text--alt fr-text--lg">
<%= t('.info_provider_description') %></p>
</div>
</div>
<div class="info fr-mb-3w">
<%= image_tag("api_entreprise/home/pictos/un-seul-compte.svg", class: %w(info--icon fr-icon--huge), alt: 'Pictogramme un seul accès') %>
<%= image_tag("api_entreprise/home/pictos/un-seul-compte.svg", class: %w(info--icon fr-icon--huge), alt: '') %>
<div class="info--text">
<h3 class="fr-h6 fr-mb-1w"><%= t('.info_account_title') %></h3>
<p class="fr-text--alt fr-text--lg">
<%= t('.info_account_description') %></p>
</div>
</div>
<div class="info fr-mb-3w">
<%= image_tag("api_entreprise/home/pictos/interfacage.svg", class: %w(info--icon fr-icon--huge), alt: 'Pictogramme un seul interfaçage') %>
<%= image_tag("api_entreprise/home/pictos/interfacage.svg", class: %w(info--icon fr-icon--huge), alt: '') %>
<div class="info--text">
<h3 class="fr-h6 fr-mb-1w"><%= t('.info_technical_title') %></h3>
<p class="fr-text--alt fr-text--lg">
Expand All @@ -48,9 +48,9 @@
<div class="fr-card fr-m-5v fr-enlarge-link fr-col-11">
<div class="fr-card__body">
<div class="fr-card__content">
<h4 class="fr-card__title">
<h3 class="fr-card__title">
<%= link_to t('.card_documentation_title'), endpoints_path %>
</h4>
</h3>
<p class="fr-card__desc"><%= t('.card_documentation_description').html_safe %></p>
</div>
</div>
Expand All @@ -59,9 +59,9 @@
<div class="fr-card fr-m-5v fr-enlarge-link fr-col-11">
<div class="fr-card__body">
<div class="fr-card__content">
<h4 class="fr-card__title">
<h3 class="fr-card__title">
<%= link_to t('.card_developers_title'), developers_path %>
</h4>
</h3>
<p class="fr-card__desc"><%= t('.card_developers_description').html_safe %></p>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<h3 class="fr-h4 fr-card__title">
<%= link_to t('.swagger_link'), developers_openapi_path %>
</h3>
<p class="fr-card__desc"><%= t('.swagger_description') %></p>
<p class="fr-card__desc"><%= t('.swagger_description').html_safe %></p>
</div>
</div>
</div>
Expand All @@ -46,7 +46,7 @@
<h3 class="fr-h4 fr-card__title">
<a href="https://status.entreprise.api.gouv.fr/"><%= t('.status_link') %></a>
</h3>
<div class="fr-card__desc" id="hyperping-badge"></div>
<div class="fr-card__desc" id="hyperping-badge" aria-live="polite"></div>
<script src="https://hyperping.io/badge.js" async></script>
<script>
window.onload = function () {
Expand Down
Loading