From d0b78be46b506a62de0d6f2e9078f9e7003acbd1 Mon Sep 17 00:00:00 2001
From: Egidio Corica <ecorica@beapi.fr>
Date: Mon, 18 Sep 2023 15:13:23 +0200
Subject: [PATCH 1/6] Add FacetWP services

---
 inc/Framework.php         |   2 +
 inc/Services/Facet_WP.php | 165 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 167 insertions(+)
 create mode 100644 inc/Services/Facet_WP.php

diff --git a/inc/Framework.php b/inc/Framework.php
index 95267cc0..810d3c06 100644
--- a/inc/Framework.php
+++ b/inc/Framework.php
@@ -4,6 +4,7 @@
 
 use BEA\Theme\Framework\Services\Acf;
 use BEA\Theme\Framework\Services\Assets;
+use BEA\Theme\Framework\Services\Facet_WP;
 use BEA\Theme\Framework\Services\Performance;
 use BEA\Theme\Framework\Services\Assets_JS_Async;
 use BEA\Theme\Framework\Services\Editor;
@@ -40,6 +41,7 @@ class Framework {
 		Svg::class,
 		Acf::class,
 		Menu::class,
+		Facet_WP::class,
 
 		// Services as Tools
 		Body_Class::class,
diff --git a/inc/Services/Facet_WP.php b/inc/Services/Facet_WP.php
new file mode 100644
index 00000000..c7eeb287
--- /dev/null
+++ b/inc/Services/Facet_WP.php
@@ -0,0 +1,165 @@
+<?php
+
+namespace BEA\Theme\Framework\Services;
+
+use BEA\Theme\Framework\Service;
+use BEA\Theme\Framework\Service_Container;
+
+class Facet_WP implements Service {
+	public function register( Service_Container $container ): void {
+	}
+
+	public function boot( Service_Container $container ): void {
+		add_filter( 'facetwp_load_assets', '__return_true' );
+		add_filter( 'facetwp_load_a11y', '__return_true' );
+		add_filter( 'facetwp_facets', [ $this, 'register_facets' ], 40 );
+		add_filter( 'facetwp_pager_html', [ $this, 'accessible_facetwp_pager_html' ], 10, 2 );
+		add_filter( 'facetwp_facet_html', [ $this, 'accessible_facetwp_labels' ], 10, 2 );
+	}
+
+	/**
+	 * Get service name
+	 *
+	 * @return string
+	 */
+	public function get_service_name(): string {
+		return 'facetwp';
+	}
+
+	/**
+	 * Register facets from config file.
+	 *
+	 * @param array $facets
+	 *
+	 * @return array
+	 * @author Egidio CORICA
+	 */
+	public function register_facets( array $facets ): array {
+
+		$filename = get_theme_file_path( 'assets/facetwp/config.json' );
+		if ( ! is_readable( $filename ) ) {
+			return $facets;
+		}
+
+		$facet_content = file_get_contents( $filename ); // phpcs:ignore
+		if ( empty( $facet_content ) ) {
+			return $facets;
+		}
+
+		$facet_content = \json_decode( $facet_content, true );
+		if (
+			JSON_ERROR_NONE !== \json_last_error()
+			|| ! is_array( $facet_content )
+			|| empty( $facet_content['facets'] )
+		) {
+			return $facets;
+		}
+
+		return wp_parse_args( $facet_content['facets'], $facets );
+	}
+
+	/**
+	 * Add custom and accessible FacetWP pagination.
+	 *
+	 * @param $output
+	 * @param $params
+	 *
+	 * @return string
+	 *
+	 * @author Egidio CORICA
+	 *
+	 */
+	public function accessible_facetwp_pager_html( $output, $params ): string {
+		$defaults    = [
+			'page'       => 1,
+			'per_page'   => 10,
+			'total_rows' => 1,
+		];
+		$params      = array_merge( $defaults, $params );
+		$output      = '';
+		$page        = (int) $params['page'];
+		$total_pages = (int) $params['total_pages'];
+
+		// Only show pagination when > 1 page
+		if ( 1 < $total_pages ) {
+
+			$text_page = esc_html__( 'Page', 'fwp-front' );
+			$text_of   = esc_html__( 'of', 'fwp-front' );
+			$step      = 10;
+
+			$output .= '<span class="facetwp-pager-label sr-only">' . "$text_page $page $text_of $total_pages</span>";
+
+			if ( $page > 1 ) {
+				$output .= '<a href="#" class="facetwp-page previouspostslink" data-page="' . ( $page - 1 ) . '">Précédent</a>';
+			} else {
+				$output .= '<span class="facetwp-page previouspostslink" aria-hidden="true" tabindex="-1" style="visibility: hidden"></span>';
+			}
+
+			if ( 3 < $page ) {
+				$output .= '<a href="#" class="facetwp-page first-page" data-page="1">
+        <span class="sr-only">Première page</span>
+        <span aria-hidden="true">1</span>
+        </a>';
+			}
+			if ( 1 < ( $page - $step ) ) {
+				$output .= '<span class="facetwp-page-more" aria-hidden="true">...</span>';
+			}
+
+			for ( $i = 2; $i > 0; $i -- ) {
+				if ( 0 < ( $page - $i ) ) {
+					$output .= '<a href="#" class="facetwp-page" data-page="' . ( $page - $i ) . '"><span class="sr-only">Page</span> ' . ( $page - $i ) . '</a>';
+				}
+			}
+
+			// Current page
+			$output .= '<a href="#" class="facetwp-page active" aria-current="true" data-page="' . $page . '"><span class="sr-only">Page courante</span> ' . $page . '</a>';
+
+			for ( $i = 1; $i <= 2; $i ++ ) {
+				if ( $total_pages >= ( $page + $i ) ) {
+					$output .= '<a href="#" class="facetwp-page" data-page="' . ( $page + $i ) . '"><span class="sr-only">Page</span> ' . ( $page + $i ) . '</a>';
+				}
+			}
+
+			if ( $total_pages > ( $page + $step ) ) {
+				$output .= '<span class="facetwp-page-more" aria-hidden="true">...</span>';
+			}
+
+			if ( $total_pages > ( $page + 2 ) ) {
+				$output .= '<a href="#" class="facetwp-page last-page" data-page="' . $total_pages . '">
+        <span class="sr-only">Dernière page</span>
+        <span aria-hidden="true">' . $total_pages . '</span>
+        </a>';
+			}
+
+			if ( $page < $total_pages && $total_pages > 1 ) {
+				$output .= '<a href="#" class="facetwp-page nextpostslink" data-page="' . ( $page + 1 ) . '">Suivant</a>';
+			} else {
+				$output .= '<span class="facetwp-page nextpostslink" aria-hidden="true" style="visibility: hidden;" tabindex="-1"></span>';
+			}
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Fix Labels for supported facets.
+	 * Put in show_label_not_empty the facets that only need to be visible in they have results.
+	 *
+	 * @param string $html
+	 * @param array $args
+	 *
+	 * @return string
+	 */
+	public function accessible_facetwp_labels( string $html, array $args ): string {
+		$show_label_not_empty = [
+			'checkboxes',
+			'radio',
+		];
+
+		if ( ( true === in_array( $args['facet']['type'], $show_label_not_empty, true ) && ! empty( $args['values'] ) ) || false === in_array( $args['facet']['type'], $show_label_not_empty, true ) ) {
+			$html = sprintf( '<label class="facetwp-label" for="%s">%s</label>%s', esc_attr( $args['facet']['name'] ), esc_html( $args['facet']['label'] ), $html );
+		}
+
+		return $html;
+	}
+}

From 448ce7aa776e016bb9f2ba01ed1c776c62bc3805 Mon Sep 17 00:00:00 2001
From: Egidio Corica <ecorica@beapi.fr>
Date: Mon, 4 Mar 2024 10:42:12 +0100
Subject: [PATCH 2/6] Add text domain and update translation

---
 inc/Services/Facet_WP.php              |  24 ++-
 languages/beapi-frontend-framework.pot | 131 +++-------------
 languages/fr_FR.mo                     | Bin 2366 -> 639 bytes
 languages/fr_FR.po                     | 205 +++++++++++++------------
 4 files changed, 140 insertions(+), 220 deletions(-)

diff --git a/inc/Services/Facet_WP.php b/inc/Services/Facet_WP.php
index c7eeb287..a79b6f31 100644
--- a/inc/Services/Facet_WP.php
+++ b/inc/Services/Facet_WP.php
@@ -90,7 +90,7 @@ public function accessible_facetwp_pager_html( $output, $params ): string {
 			$output .= '<span class="facetwp-pager-label sr-only">' . "$text_page $page $text_of $total_pages</span>";
 
 			if ( $page > 1 ) {
-				$output .= '<a href="#" class="facetwp-page previouspostslink" data-page="' . ( $page - 1 ) . '">Précédent</a>';
+				$output .= '<a href="#" class="facetwp-page previouspostslink" data-page="' . ( $page - 1 ) . '">' . __( 'Previous', 'framework-textdomain' ) . '</a>';
 			} else {
 				$output .= '<span class="facetwp-page previouspostslink" aria-hidden="true" tabindex="-1" style="visibility: hidden"></span>';
 			}
@@ -107,16 +107,16 @@ public function accessible_facetwp_pager_html( $output, $params ): string {
 
 			for ( $i = 2; $i > 0; $i -- ) {
 				if ( 0 < ( $page - $i ) ) {
-					$output .= '<a href="#" class="facetwp-page" data-page="' . ( $page - $i ) . '"><span class="sr-only">Page</span> ' . ( $page - $i ) . '</a>';
+					$output .= '<a href="#" class="facetwp-page" data-page="' . ( $page - $i ) . '"><span class="sr-only">' . __( 'Page', 'framework-textdomain' ) . '</span> ' . ( $page - $i ) . '</a>';
 				}
 			}
 
 			// Current page
-			$output .= '<a href="#" class="facetwp-page active" aria-current="true" data-page="' . $page . '"><span class="sr-only">Page courante</span> ' . $page . '</a>';
+			$output .= '<a href="#" class="facetwp-page active" aria-current="true" data-page="' . $page . '"><span class="sr-only">' . __( 'Current page', 'framework-textdomain' ) . '</span> ' . $page . '</a>';
 
 			for ( $i = 1; $i <= 2; $i ++ ) {
 				if ( $total_pages >= ( $page + $i ) ) {
-					$output .= '<a href="#" class="facetwp-page" data-page="' . ( $page + $i ) . '"><span class="sr-only">Page</span> ' . ( $page + $i ) . '</a>';
+					$output .= '<a href="#" class="facetwp-page" data-page="' . ( $page + $i ) . '"><span class="sr-only">' . __( 'Page', 'framework-textdomain' ) . '</span> ' . ( $page + $i ) . '</a>';
 				}
 			}
 
@@ -126,13 +126,13 @@ public function accessible_facetwp_pager_html( $output, $params ): string {
 
 			if ( $total_pages > ( $page + 2 ) ) {
 				$output .= '<a href="#" class="facetwp-page last-page" data-page="' . $total_pages . '">
-        <span class="sr-only">Dernière page</span>
+        <span class="sr-only">' . __( 'Last page', 'framework-textdomain' ) . '</span>
         <span aria-hidden="true">' . $total_pages . '</span>
         </a>';
 			}
 
 			if ( $page < $total_pages && $total_pages > 1 ) {
-				$output .= '<a href="#" class="facetwp-page nextpostslink" data-page="' . ( $page + 1 ) . '">Suivant</a>';
+				$output .= '<a href="#" class="facetwp-page nextpostslink" data-page="' . ( $page + 1 ) . '">' . __( 'Next', 'framework-textdomain' ) . '</a>';
 			} else {
 				$output .= '<span class="facetwp-page nextpostslink" aria-hidden="true" style="visibility: hidden;" tabindex="-1"></span>';
 			}
@@ -157,7 +157,17 @@ public function accessible_facetwp_labels( string $html, array $args ): string {
 		];
 
 		if ( ( true === in_array( $args['facet']['type'], $show_label_not_empty, true ) && ! empty( $args['values'] ) ) || false === in_array( $args['facet']['type'], $show_label_not_empty, true ) ) {
-			$html = sprintf( '<label class="facetwp-label" for="%s">%s</label>%s', esc_attr( $args['facet']['name'] ), esc_html( $args['facet']['label'] ), $html );
+			$label = $args['facet']['label'];
+			if ( function_exists( 'facetwp_i18n' ) ) {
+				$label = facetwp_i18n( $label );
+			}
+
+			$html = sprintf( '<label class="facetwp-label" for="%s">%s</label>%s', esc_attr( $args['facet']['name'] ), esc_html( $label ), $html );
+
+			// Add id attribute to per_page select
+			if ( 'per_page' === $args['facet']['name'] ) {
+				$html = str_replace( '<select class="facetwp-per-page-select">', '<select class="facetwp-per-page-select" id="per_page">', $html );
+			}
 		}
 
 		return $html;
diff --git a/languages/beapi-frontend-framework.pot b/languages/beapi-frontend-framework.pot
index dadf78be..41f2ef70 100644
--- a/languages/beapi-frontend-framework.pot
+++ b/languages/beapi-frontend-framework.pot
@@ -1,4 +1,4 @@
-# Copyright (C) 2022 BeAPI
+# Copyright (C) 2024 BeAPI
 # This file is distributed under the .
 msgid ""
 msgstr ""
@@ -9,10 +9,10 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"POT-Creation-Date: 2022-06-30T08:09:55+00:00\n"
+"POT-Creation-Date: 2024-03-04T09:37:43+00:00\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"X-Generator: WP-CLI 2.6.0\n"
-"X-Domain: beapi-frontend-framework\n"
+"X-Generator: WP-CLI 2.9.0\n"
+"X-Domain: framework-textdomain\n"
 
 #. Theme Name of the theme
 #. Description of the theme
@@ -31,123 +31,32 @@ msgstr ""
 msgid "http://www.beapi.fr"
 msgstr ""
 
-#: components/blocks/footer.php:4
-#: components/blocks/skip-links.php:12
-msgid "Footer"
+#: inc/Services/Acf.php:55
+msgid "This theme can't work without ACF plugin. <a href=\"%s\">Please login to admin</a>, and activate it !"
 msgstr ""
 
-#: components/blocks/header.php:4
-msgid "Header"
+#: inc/Services/Facet_WP.php:93
+msgid "Previous"
 msgstr ""
 
-#: components/blocks/header.php:14
-msgid "Open/Close the menu"
+#: inc/Services/Facet_WP.php:110
+#: inc/Services/Facet_WP.php:119
+msgid "Page"
 msgstr ""
 
-#: components/blocks/header.php:17
-msgid "Main navigation"
+#: inc/Services/Facet_WP.php:115
+msgid "Current page"
 msgstr ""
 
-#: components/blocks/skip-links.php:4
-msgid "Fast access links"
+#: inc/Services/Facet_WP.php:129
+msgid "Last page"
 msgstr ""
 
-#: components/blocks/skip-links.php:6
-msgid "Main navigation menu"
+#: inc/Services/Facet_WP.php:135
+msgid "Next"
 msgstr ""
 
-#: components/blocks/skip-links.php:9
-#: header.php:26
-msgid "Main content"
-msgstr ""
-
-#: inc/Helpers/Formatting/Link.php:144
-msgid "New window"
-msgstr ""
-
-#: inc/Helpers/Formatting/Share.php:53
-msgid "Share on Facebook"
-msgstr ""
-
-#: inc/Helpers/Formatting/Share.php:64
-msgid "Share on Twitter"
-msgstr ""
-
-#: inc/Helpers/Formatting/Share.php:75
-msgid "Share on Linkedin"
-msgstr ""
-
-#: inc/Helpers/Formatting/Share.php:86
-msgid "Share on Email"
-msgstr ""
-
-#: inc/Helpers/Menu_Walker.php:26
-msgid "Toggle menu"
-msgstr ""
-
-#: inc/Services/Editor.php:76
-msgid "Dark"
-msgstr ""
-
-#: inc/Services/Editor.php:81
-msgid "Light"
-msgstr ""
-
-#: inc/Services/Editor.php:86
-msgid "Primary"
-msgstr ""
-
-#: inc/Services/Editor.php:91
-msgid "Secondary"
-msgstr ""
-
-#: inc/Services/Editor.php:102
-msgid "Title 6"
-msgstr ""
-
-#: inc/Services/Editor.php:108
-msgid "Title 5"
-msgstr ""
-
-#: inc/Services/Editor.php:114
-msgid "Title 4"
-msgstr ""
-
-#: inc/Services/Editor.php:120
-msgid "Title 3"
-msgstr ""
-
-#: inc/Services/Editor.php:126
-msgid "Title 2"
-msgstr ""
-
-#: inc/Services/Editor.php:132
-msgid "Title 1"
-msgstr ""
-
-#: inc/Services/Editor_Patterns.php:40
-msgid "Common"
-msgstr ""
-
-#. translators: %s: file name.
-#: inc/Services/Editor_Patterns.php:125
-msgid "Could not register file \"%s\" as a block pattern (\"Slug\" field missing)"
-msgstr ""
-
-#. translators: %1s: file name; %2s: slug value found.
-#: inc/Services/Editor_Patterns.php:138
-msgid "Could not register file \"%1$s\" as a block pattern (invalid slug \"%2$s\")"
-msgstr ""
-
-#. translators: %1s: file name; %2s: slug value found.
-#: inc/Services/Editor_Patterns.php:155
-msgid "Could not register file \"%s\" as a block pattern (\"Title\" field missing)"
-msgstr ""
-
-#: inc/Services/Menu.php:37
-msgid "Main menu"
-msgstr ""
-
-#: inc/Services/Menu.php:38
-msgid "Footer menu"
+#: patterns/media-text.php
+msgctxt "Pattern title"
+msgid "Media Text"
 msgstr ""
diff --git a/languages/fr_FR.mo b/languages/fr_FR.mo
index 78ec3186b5d83f4341002a843c5cdd299941c2db..8ac2242b72f4d6b3d379265739ae68dec4b063ad 100644
GIT binary patch
delta 262
zcmdld^q-~vo)F7a1|VPsVi_QI0b+I_&H-W&=m26KAnpWWP9UBJ#4JF(0Ejt&cqtIi
zXJlYl2c&s{*pG>Ufe%Q>0BMjp*+7~bNEZWXpfa#M%s?6n^uUGz<ro;8ON)w9^GXy7
z64O%|d=iVHEWgx>5{7`H)UwR{(&EXBSmp|t=o%R78ki^;8dw=yY8x0%_GdlAY^-NA
zS%yv3FaW4qAvwRaC^4@jmBA&oC@=HyilS7Asllb0Wk7MDafeqXA6}UPw2lD)fR8h|

literal 2366
zcmcJPO=u)V6vs=AU*qb!tFEqJ6j3ojJM*!+2@|rgn`B}zAH!x`ym+XYuJn}Yu4=2g
zXIwn22f>RVA}SshRy?@TiziX=Ha9^Jp1dgH(Ua^=Q1JhH%9)H3528i){QA9mQ?K58
zRqu!6Q|~a0hw(m$_sDgO&4RyyG_G9F*iGOE;2L-pY=FObdHx2*rXXJekAbg&WdAOB
z8+h5v`{0d`KLw9~pMkf61Mn#LHF!7pJy-&-fp>wwgExc6;Dqc?f_H$AfaI^{xdPq^
z`2tAxk*D$OdtUN<-SbV5_W2%o88LqdlAp5(A_1QTyWkg~0;jP!#rFnyFZeb{@q7Z(
zem)2Bu&?k#@qX*|-+{F6pTT>;UqQ<E(OZW9dlDr584wR^;fM0@0(czkf;9h%=UX7<
z>m!i-e(Cv*=Z~J(Jf{#8*_{Asof(iyOflS#_W`^xEn=gyKrvy9#U6lSpcD*cXD9K}
z8VARH5GWqnEBT>8^`qKS+?3;k;{*hxx)_uvY=_-G6pK1Ogl~$EEt@1U8pz|2Ym;#+
zBjqw_`L2p3pMI?RsGH`(alzZM>Fn`TWSG@_M(Li2RmfeON3g5GZuTG6Ib@aT9sGS7
z&LsRN$~mQ@f3r+WWwHF*IxE8Nv4(IN7oCoDj>k&xIo2=+F?jGq>YP0zMF`b~in<xw
z6iV}s(V5g<C~OL~7CjY-Od)B1k%tRy$v*EZ9hyGdPNgm{$HqyXb>(onX;mWZMYbcc
zepq~Ug_YcBzM2RXvz<T1hUmz)F?(ap1~xB4rN^39Ur{w!5k0SZ);v#nKIQqe=V{h5
zQH1IiQ8lf3QFgLmJq#{L>kwF-pOgG-bDcMAk%JH)B9VP#_jq-#GFK^`m#MK?u<0Td
z2Ium~1uawO-7HI8y<CQ2m|CQJ&e*8z@|29rNI@dYZ7EU}?D~cA;TJA7w}bPtr^tV>
zA~IR$wMwlPROW-q0<X^3E7d0|wMwP5focXVE3}J6W^A29qoZ6zGH6MW9FXgL*OoTd
zH&@4TVfUrwVO@jP#S~65`EpiHV-$RmcaVA~v!&-+jbLGHN4|EY4OVr>Ap23BFSJ!w
zYR0)0anLX}adocKLUc>DMLzson$i3Wug)%(o)6ZfmUg(^ra=iaerm1?{fa@&k?%vZ
z!qx`+daw^iY&}U0u16bn3-Jv0J24K9<*~p~r8z~1lIG~5IzG69yJ|CKd6?sVb-D`1
z{yxua$b<Km>&GSTNQ!G-+-W)cUwOl=Ctt{Hl5&67$yFlsOS#b5|K!MbgGo<2CTUxV
zD=xL;;ZLu=kDf5N>bS*;3?*wS8B+F|I7)02J%OiQlagjtXM>M3$(C_eEczTZ2bfr;
zJ1RwahW{9eTcb8Hw(-lt$GC}%XW5p?doo6Occq3aY;`;DS!K%&X%i~+=)$6fC`|hv
zLZ3}k8oRVqaxRNTGE%wR@=-IH(2g3)g!VvFL1Uubs-6`2u)R!ZibgY`DO%2irf5DB
NnxYL&Xigsz=^y8Gb*KOU

diff --git a/languages/fr_FR.po b/languages/fr_FR.po
index f05cf192..83d9eba4 100644
--- a/languages/fr_FR.po
+++ b/languages/fr_FR.po
@@ -5,8 +5,8 @@ msgstr ""
 "Project-Id-Version: Be API Frontend Framework 1.0.0\n"
 "Report-Msgid-Bugs-To: https://wordpress.org/support/theme/beapi-frontend-"
 "framework\n"
-"POT-Creation-Date: 2022-06-30T08:09:55+00:00\n"
-"PO-Revision-Date: 2022-07-08 17:01+0200\n"
+"POT-Creation-Date: 2024-03-04T09:37:43+00:00\n"
+"PO-Revision-Date: 2024-03-04 10:39+0100\n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language: fr\n"
@@ -14,7 +14,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 3.1\n"
+"X-Generator: Poedit 3.3.2\n"
 "X-Domain: beapi-frontend-framework\n"
 
 #. Theme Name of the theme
@@ -34,130 +34,131 @@ msgstr ""
 msgid "http://www.beapi.fr"
 msgstr ""
 
-#: components/blocks/footer.php:4 components/blocks/skip-links.php:12
-msgid "Footer"
-msgstr "Pied de Page"
+#: inc/Services/Acf.php:55
+msgid ""
+"This theme can't work without ACF plugin. <a href=\"%s\">Please login to "
+"admin</a>, and activate it !"
+msgstr ""
 
-#: components/blocks/header.php:4
-msgid "Header"
-msgstr "Entête"
+#: inc/Services/Facet_WP.php:93
+msgid "Previous"
+msgstr "Précédent"
 
-#: components/blocks/header.php:14
-msgid "Open/Close the menu"
-msgstr "Ouvrir/Fermer le menu"
+#: inc/Services/Facet_WP.php:110 inc/Services/Facet_WP.php:119
+msgid "Page"
+msgstr ""
 
-#: components/blocks/header.php:17
-msgid "Main navigation"
-msgstr "Navigation principale"
+#: inc/Services/Facet_WP.php:115
+msgid "Current page"
+msgstr "Page courante"
 
-#: components/blocks/skip-links.php:4
-msgid "Fast access links"
-msgstr "Liens d’accès rapide"
+#: inc/Services/Facet_WP.php:129
+msgid "Last page"
+msgstr "Dernière page"
 
-#: components/blocks/skip-links.php:6
-msgid "Main navigation menu"
-msgstr "Menu de navigation principal"
+#: inc/Services/Facet_WP.php:135
+msgid "Next"
+msgstr "Suivant"
 
-#: components/blocks/skip-links.php:9 header.php:26
-msgid "Main content"
-msgstr "Contenu principal"
+#: patterns/media-text.php
+msgctxt "Pattern title"
+msgid "Media Text"
+msgstr ""
 
-#: inc/Helpers/Formatting/Link.php:144
-msgid "New window"
-msgstr "Nouvelle fenêtre"
+#~ msgid "Footer"
+#~ msgstr "Pied de Page"
 
-#: inc/Helpers/Formatting/Share.php:53
-msgid "Share on Facebook"
-msgstr "Partager sur Facebook"
+#~ msgid "Header"
+#~ msgstr "Entête"
 
-#: inc/Helpers/Formatting/Share.php:64
-msgid "Share on Twitter"
-msgstr "Partager sur Twitter"
+#~ msgid "Open/Close the menu"
+#~ msgstr "Ouvrir/Fermer le menu"
 
-#: inc/Helpers/Formatting/Share.php:75
-msgid "Share on Linkedin"
-msgstr "Partager sur Linkedin"
+#~ msgid "Main navigation"
+#~ msgstr "Navigation principale"
 
-#: inc/Helpers/Formatting/Share.php:86
-msgid "Share on Email"
-msgstr "Partager par email"
+#~ msgid "Fast access links"
+#~ msgstr "Liens d’accès rapide"
 
-#: inc/Helpers/Menu_Walker.php:26
-msgid "Toggle menu"
-msgstr "Ouvrir/Fermer le menu"
+#~ msgid "Main navigation menu"
+#~ msgstr "Menu de navigation principal"
 
-#: inc/Services/Editor.php:76
-msgid "Dark"
-msgstr "Sombre"
+#~ msgid "Main content"
+#~ msgstr "Contenu principal"
 
-#: inc/Services/Editor.php:81
-msgid "Light"
-msgstr "Clair"
+#~ msgid "New window"
+#~ msgstr "Nouvelle fenêtre"
 
-#: inc/Services/Editor.php:86
-msgid "Primary"
-msgstr "Primaire"
+#~ msgid "Share on Facebook"
+#~ msgstr "Partager sur Facebook"
 
-#: inc/Services/Editor.php:91
-msgid "Secondary"
-msgstr "Secondaire"
+#~ msgid "Share on Twitter"
+#~ msgstr "Partager sur Twitter"
 
-#: inc/Services/Editor.php:102
-msgid "Title 6"
-msgstr "Titre de niveau 6"
+#~ msgid "Share on Linkedin"
+#~ msgstr "Partager sur Linkedin"
 
-#: inc/Services/Editor.php:108
-msgid "Title 5"
-msgstr "Titre de niveau 5"
+#~ msgid "Share on Email"
+#~ msgstr "Partager par email"
 
-#: inc/Services/Editor.php:114
-msgid "Title 4"
-msgstr "Titre de niveau 4"
+#~ msgid "Toggle menu"
+#~ msgstr "Ouvrir/Fermer le menu"
 
-#: inc/Services/Editor.php:120
-msgid "Title 3"
-msgstr "Titre de niveau 3"
+#~ msgid "Dark"
+#~ msgstr "Sombre"
 
-#: inc/Services/Editor.php:126
-msgid "Title 2"
-msgstr "Titre de niveau 2"
+#~ msgid "Light"
+#~ msgstr "Clair"
 
-#: inc/Services/Editor.php:132
-msgid "Title 1"
-msgstr "Titre de niveau 1"
+#~ msgid "Primary"
+#~ msgstr "Primaire"
 
-#: inc/Services/Editor_Patterns.php:40
-msgid "Common"
-msgstr "Général"
+#~ msgid "Secondary"
+#~ msgstr "Secondaire"
 
-#. translators: %s: file name.
-#: inc/Services/Editor_Patterns.php:125
-msgid ""
-"Could not register file \"%s\" as a block pattern (\"Slug\" field missing)"
-msgstr ""
-"Impossible de déclarer la composition de blocs à partir du fichier \"%s"
-"\" (Le champ \"Slug\" est manquant)"
+#~ msgid "Title 6"
+#~ msgstr "Titre de niveau 6"
 
-#. translators: %1s: file name; %2s: slug value found.
-#: inc/Services/Editor_Patterns.php:138
-msgid ""
-"Could not register file \"%1$s\" as a block pattern (invalid slug \"%2$s\")"
-msgstr ""
-"Impossible de déclarer la composition de blocs à partir du fichier \"%1$s"
-"\" (Le slug \"%2$s\" n'est pas valide)"
+#~ msgid "Title 5"
+#~ msgstr "Titre de niveau 5"
 
-#. translators: %1s: file name; %2s: slug value found.
-#: inc/Services/Editor_Patterns.php:155
-msgid ""
-"Could not register file \"%s\" as a block pattern (\"Title\" field missing)"
-msgstr ""
-"Impossible de déclarer la composition de blocs à partir du fichier \"%s"
-"\" (Le champ \"Title\" est manquant)"
+#~ msgid "Title 4"
+#~ msgstr "Titre de niveau 4"
+
+#~ msgid "Title 3"
+#~ msgstr "Titre de niveau 3"
+
+#~ msgid "Title 2"
+#~ msgstr "Titre de niveau 2"
+
+#~ msgid "Title 1"
+#~ msgstr "Titre de niveau 1"
+
+#~ msgid "Common"
+#~ msgstr "Général"
+
+#~ msgid ""
+#~ "Could not register file \"%s\" as a block pattern (\"Slug\" field missing)"
+#~ msgstr ""
+#~ "Impossible de déclarer la composition de blocs à partir du fichier "
+#~ "\"%s\" (Le champ \"Slug\" est manquant)"
+
+#~ msgid ""
+#~ "Could not register file \"%1$s\" as a block pattern (invalid slug "
+#~ "\"%2$s\")"
+#~ msgstr ""
+#~ "Impossible de déclarer la composition de blocs à partir du fichier "
+#~ "\"%1$s\" (Le slug \"%2$s\" n'est pas valide)"
+
+#~ msgid ""
+#~ "Could not register file \"%s\" as a block pattern (\"Title\" field "
+#~ "missing)"
+#~ msgstr ""
+#~ "Impossible de déclarer la composition de blocs à partir du fichier "
+#~ "\"%s\" (Le champ \"Title\" est manquant)"
 
-#: inc/Services/Menu.php:37
-msgid "Main menu"
-msgstr "Menu principal"
+#~ msgid "Main menu"
+#~ msgstr "Menu principal"
 
-#: inc/Services/Menu.php:38
-msgid "Footer menu"
-msgstr "Menu pied de page"
+#~ msgid "Footer menu"
+#~ msgstr "Menu pied de page"

From 8ac1dc1ce56181efc5a2dd32fc24db9d85f64eda Mon Sep 17 00:00:00 2001
From: Marie Comet <mcomet@beapi.fr>
Date: Wed, 29 May 2024 16:52:43 +0200
Subject: [PATCH 3/6] FacetWP Service : add customization to facet pager links
 // remove custom labels

---
 inc/Services/Facet_WP.php | 76 +++++++++++++++++++++------------------
 1 file changed, 42 insertions(+), 34 deletions(-)

diff --git a/inc/Services/Facet_WP.php b/inc/Services/Facet_WP.php
index a79b6f31..9180e424 100644
--- a/inc/Services/Facet_WP.php
+++ b/inc/Services/Facet_WP.php
@@ -14,7 +14,7 @@ public function boot( Service_Container $container ): void {
 		add_filter( 'facetwp_load_a11y', '__return_true' );
 		add_filter( 'facetwp_facets', [ $this, 'register_facets' ], 40 );
 		add_filter( 'facetwp_pager_html', [ $this, 'accessible_facetwp_pager_html' ], 10, 2 );
-		add_filter( 'facetwp_facet_html', [ $this, 'accessible_facetwp_labels' ], 10, 2 );
+		add_filter( 'facetwp_facet_pager_link', [ $this, 'facetwp_facet_pager_link' ], 10, 2 );
 	}
 
 	/**
@@ -60,6 +60,8 @@ public function register_facets( array $facets ): array {
 
 	/**
 	 * Add custom and accessible FacetWP pagination.
+	 * This function apply only with the old way to display a pager : facetwp_display( 'pager' );
+	 * For customization of the pagination facet, see facetwp_facet_pager_link function.
 	 *
 	 * @param $output
 	 * @param $params
@@ -90,33 +92,37 @@ public function accessible_facetwp_pager_html( $output, $params ): string {
 			$output .= '<span class="facetwp-pager-label sr-only">' . "$text_page $page $text_of $total_pages</span>";
 
 			if ( $page > 1 ) {
-				$output .= '<a href="#" class="facetwp-page previouspostslink" data-page="' . ( $page - 1 ) . '">' . __( 'Previous', 'framework-textdomain' ) . '</a>';
+				$output .= sprintf(
+					'<button class="btn facetwp-page previouspostslink" data-page="%s">' . __( 'Previous', 'framework-textdomain' ) . '</button>',
+					( $page - 1 )
+				);
 			} else {
 				$output .= '<span class="facetwp-page previouspostslink" aria-hidden="true" tabindex="-1" style="visibility: hidden"></span>';
 			}
 
 			if ( 3 < $page ) {
-				$output .= '<a href="#" class="facetwp-page first-page" data-page="1">
-        <span class="sr-only">Première page</span>
-        <span aria-hidden="true">1</span>
-        </a>';
+				$output .= sprintf(
+					'<button class="btn facetwp-page first-page" data-page="1"><span class="sr-only">%s</span><span aria-hidden="true">1</span></button>',
+					__( 'First page', 'framework-textdomain' )
+				);
 			}
+
 			if ( 1 < ( $page - $step ) ) {
 				$output .= '<span class="facetwp-page-more" aria-hidden="true">...</span>';
 			}
 
 			for ( $i = 2; $i > 0; $i -- ) {
 				if ( 0 < ( $page - $i ) ) {
-					$output .= '<a href="#" class="facetwp-page" data-page="' . ( $page - $i ) . '"><span class="sr-only">' . __( 'Page', 'framework-textdomain' ) . '</span> ' . ( $page - $i ) . '</a>';
+					$output .= '<button class="btn facetwp-page" data-page="' . ( $page - $i ) . '"><span class="sr-only">' . __( 'Page', 'framework-textdomain' ) . '</span> ' . ( $page - $i ) . '</button>';
 				}
 			}
 
 			// Current page
-			$output .= '<a href="#" class="facetwp-page active" aria-current="true" data-page="' . $page . '"><span class="sr-only">' . __( 'Current page', 'framework-textdomain' ) . '</span> ' . $page . '</a>';
+			$output .= '<span class="facetwp-page active" aria-current="true" data-page="' . $page . '"><span class="sr-only">' . __( 'Current page', 'framework-textdomain' ) . '</span> ' . $page . '</span>';
 
 			for ( $i = 1; $i <= 2; $i ++ ) {
 				if ( $total_pages >= ( $page + $i ) ) {
-					$output .= '<a href="#" class="facetwp-page" data-page="' . ( $page + $i ) . '"><span class="sr-only">' . __( 'Page', 'framework-textdomain' ) . '</span> ' . ( $page + $i ) . '</a>';
+					$output .= '<button class="btn facetwp-page" data-page="' . ( $page + $i ) . '"><span class="sr-only">' . __( 'Page', 'framework-textdomain' ) . '</span> ' . ( $page + $i ) . '</button>';
 				}
 			}
 
@@ -125,14 +131,15 @@ public function accessible_facetwp_pager_html( $output, $params ): string {
 			}
 
 			if ( $total_pages > ( $page + 2 ) ) {
-				$output .= '<a href="#" class="facetwp-page last-page" data-page="' . $total_pages . '">
-        <span class="sr-only">' . __( 'Last page', 'framework-textdomain' ) . '</span>
-        <span aria-hidden="true">' . $total_pages . '</span>
-        </a>';
+				$output .= sprintf(
+					'<button class="btn facetwp-page last-page" data-page="%1$s"><span class="sr-only">%2$s</span><span aria-hidden="true">%1$s</span></button>',
+					$total_pages,
+					__( 'Last page', 'framework-textdomain' )
+				);
 			}
 
 			if ( $page < $total_pages && $total_pages > 1 ) {
-				$output .= '<a href="#" class="facetwp-page nextpostslink" data-page="' . ( $page + 1 ) . '">' . __( 'Next', 'framework-textdomain' ) . '</a>';
+				$output .= '<button class="btn facetwp-page nextpostslink" data-page="' . ( $page + 1 ) . '">' . __( 'Next', 'framework-textdomain' ) . '</button>';
 			} else {
 				$output .= '<span class="facetwp-page nextpostslink" aria-hidden="true" style="visibility: hidden;" tabindex="-1"></span>';
 			}
@@ -142,32 +149,33 @@ public function accessible_facetwp_pager_html( $output, $params ): string {
 	}
 
 	/**
-	 * Fix Labels for supported facets.
-	 * Put in show_label_not_empty the facets that only need to be visible in they have results.
+	 * Customize pagination facet output
+	 * This function apply only on pagination facets : facetwp_display( 'facet', 'pagination' );
+	 * For customization of the old way to display a pager, see accessible_facetwp_pager_html function.
+	 *
+	 * https://facetwp.com/help-center/developers/hooks/output-hooks/facetwp_facet_pager_link/
 	 *
-	 * @param string $html
-	 * @param array $args
+	 * @param $output
+	 * @param $params
 	 *
 	 * @return string
+	 *
+	 * @author Marie Comet
+	 *
 	 */
-	public function accessible_facetwp_labels( string $html, array $args ): string {
-		$show_label_not_empty = [
-			'checkboxes',
-			'radio',
-		];
-
-		if ( ( true === in_array( $args['facet']['type'], $show_label_not_empty, true ) && ! empty( $args['values'] ) ) || false === in_array( $args['facet']['type'], $show_label_not_empty, true ) ) {
-			$label = $args['facet']['label'];
-			if ( function_exists( 'facetwp_i18n' ) ) {
-				$label = facetwp_i18n( $label );
-			}
+	public function facetwp_facet_pager_link( $html, $params ): string {
+		// Replace current link by a span
+		if ( str_contains( $html, 'active' ) ) {
+			$html = str_replace( '<a', '<span', $html );
+			$html = str_replace( '</a>', '</span>', $html );
+		}
 
-			$html = sprintf( '<label class="facetwp-label" for="%s">%s</label>%s', esc_attr( $args['facet']['name'] ), esc_html( $label ), $html );
+		// Replace links by buttons and add class
+		$html = str_replace( [ '<a class="', '/a>' ], [ '<button class="btn ', '/button>' ], $html );
 
-			// Add id attribute to per_page select
-			if ( 'per_page' === $args['facet']['name'] ) {
-				$html = str_replace( '<select class="facetwp-per-page-select">', '<select class="facetwp-per-page-select" id="per_page">', $html );
-			}
+		// Remove link tag for dots
+		if ( 'dots' === $params['extra_class'] ) {
+			$html = str_replace( '<a class="facetwp-page dots">…</a>', '<span class="facetwp-page dots">…</span>', $html );
 		}
 
 		return $html;

From 6c4caf33a122e4e3938f0ce2b3af790774541c19 Mon Sep 17 00:00:00 2001
From: Marie Comet <mcomet@beapi.fr>
Date: Fri, 5 Jul 2024 11:23:22 +0200
Subject: [PATCH 4/6] FacetWP Service : remove load_assets filter // Simplify
 labels

---
 inc/Services/Facet_WP.php | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/inc/Services/Facet_WP.php b/inc/Services/Facet_WP.php
index 9180e424..7a0771dc 100644
--- a/inc/Services/Facet_WP.php
+++ b/inc/Services/Facet_WP.php
@@ -10,11 +10,11 @@ public function register( Service_Container $container ): void {
 	}
 
 	public function boot( Service_Container $container ): void {
-		add_filter( 'facetwp_load_assets', '__return_true' );
 		add_filter( 'facetwp_load_a11y', '__return_true' );
 		add_filter( 'facetwp_facets', [ $this, 'register_facets' ], 40 );
 		add_filter( 'facetwp_pager_html', [ $this, 'accessible_facetwp_pager_html' ], 10, 2 );
 		add_filter( 'facetwp_facet_pager_link', [ $this, 'facetwp_facet_pager_link' ], 10, 2 );
+		add_filter( 'facetwp_facet_html', [ $this, 'facetwp_add_labels' ], 10, 2 );
 	}
 
 	/**
@@ -180,4 +180,32 @@ public function facetwp_facet_pager_link( $html, $params ): string {
 
 		return $html;
 	}
+
+	/**
+	 * Add fake labels to all facets
+	 * Put in $add_label_if_not_empty the facets types for which you want to display the label *only* if the facet is not empty.
+	 *
+	 * @param string $html
+	 * @param array $args
+	 *
+	 * @return string
+	 */
+	public function facetwp_add_labels( string $html, array $args ): string {
+		$add_label_if_not_empty = [
+			'checkboxes',
+			'pager',
+			'reset',
+		];
+
+		if ( ( true === in_array( $args['facet']['type'], $add_label_if_not_empty, true ) && ! empty( $args['values'] ) ) || false === in_array( $args['facet']['type'], $add_label_if_not_empty, true ) ) {
+			$label = $args['facet']['label'];
+			if ( function_exists( 'facetwp_i18n' ) ) {
+				$label = facetwp_i18n( $label );
+			}
+
+			$html = sprintf( '<p aria-hidden="true" class="facetwp-label">%s</p>%s', esc_html( $label ), $html );
+		}
+
+		return $html;
+	}
 }

From ac3253d48cdaecc8aed615b2f22e77f4879c9e80 Mon Sep 17 00:00:00 2001
From: Marie Comet <mcomet@beapi.fr>
Date: Fri, 5 Jul 2024 12:04:37 +0200
Subject: [PATCH 5/6] FacetWP Service : Add aria label to per page select //
 Allow to exclude facets by names

---
 inc/Services/Facet_WP.php | 45 ++++++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/inc/Services/Facet_WP.php b/inc/Services/Facet_WP.php
index 7a0771dc..ba58b899 100644
--- a/inc/Services/Facet_WP.php
+++ b/inc/Services/Facet_WP.php
@@ -182,8 +182,9 @@ public function facetwp_facet_pager_link( $html, $params ): string {
 	}
 
 	/**
-	 * Add fake labels to all facets
-	 * Put in $add_label_if_not_empty the facets types for which you want to display the label *only* if the facet is not empty.
+	 * Add labels or aria-label to facets
+	 * Put in $excluded_facet_names the facets names for which you want to do not add the label.
+	 * Put in $excluded_empty_facets the facets types for which you want to hide the label if the facet is empty.
 	 *
 	 * @param string $html
 	 * @param array $args
@@ -191,21 +192,41 @@ public function facetwp_facet_pager_link( $html, $params ): string {
 	 * @return string
 	 */
 	public function facetwp_add_labels( string $html, array $args ): string {
-		$add_label_if_not_empty = [
+		$facet_name  = $args['facet']['name'];
+		$facet_label = $args['facet']['label'];
+		if ( function_exists( 'facetwp_i18n' ) ) {
+			$facet_label = facetwp_i18n( $facet_label );
+		}
+
+		// Return default HTML if the facet is excluded by its name
+		$excluded_facet_names = [];
+		if ( true === in_array( $facet_name, $excluded_facet_names, true ) ) {
+			return $html;
+		}
+
+		// Add aria-label attribute to per_page select
+		if ( 'per_page' === $facet_name ) {
+			return str_replace(
+				'<select class="facetwp-per-page-select">',
+				sprintf(
+					'<select class="facetwp-per-page-select" aria-label="%s">',
+					esc_attr( $facet_label )
+				),
+				$html
+			);
+		}
+
+		// Return default HTML if these facets are empty
+		$excluded_empty_facets = [
 			'checkboxes',
 			'pager',
 			'reset',
 		];
-
-		if ( ( true === in_array( $args['facet']['type'], $add_label_if_not_empty, true ) && ! empty( $args['values'] ) ) || false === in_array( $args['facet']['type'], $add_label_if_not_empty, true ) ) {
-			$label = $args['facet']['label'];
-			if ( function_exists( 'facetwp_i18n' ) ) {
-				$label = facetwp_i18n( $label );
-			}
-
-			$html = sprintf( '<p aria-hidden="true" class="facetwp-label">%s</p>%s', esc_html( $label ), $html );
+		if ( true === in_array( $args['facet']['type'], $excluded_empty_facets, true ) && empty( $args['values'] ) ) {
+			return $html;
 		}
 
-		return $html;
+		// Add fake labels
+		return sprintf( '<p aria-hidden="true" class="facetwp-label">%s</p>%s', esc_html( $facet_label ), $html );
 	}
 }

From ffb033cd17a0402396f00d343425e78866e5f266 Mon Sep 17 00:00:00 2001
From: Marie Comet <mcomet@beapi.fr>
Date: Thu, 25 Jul 2024 12:07:52 +0200
Subject: [PATCH 6/6] apply FacetWP Service review fixes

---
 inc/Services/Facet_WP.php | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/inc/Services/Facet_WP.php b/inc/Services/Facet_WP.php
index ba58b899..2825c460 100644
--- a/inc/Services/Facet_WP.php
+++ b/inc/Services/Facet_WP.php
@@ -47,11 +47,13 @@ public function register_facets( array $facets ): array {
 		}
 
 		$facet_content = \json_decode( $facet_content, true );
-		if (
-			JSON_ERROR_NONE !== \json_last_error()
-			|| ! is_array( $facet_content )
-			|| empty( $facet_content['facets'] )
-		) {
+		try {
+			$facet_content = \json_decode( $facet_content, true, 512, JSON_THROW_ON_ERROR );
+		} catch ( \JSONException $e ) {
+			return $facets;
+		}
+
+		if ( ! is_array( $facet_content ) || empty( $facet_content['facets'] ) ) {
 			return $facets;
 		}
 
@@ -199,8 +201,8 @@ public function facetwp_add_labels( string $html, array $args ): string {
 		}
 
 		// Return default HTML if the facet is excluded by its name
-		$excluded_facet_names = [];
-		if ( true === in_array( $facet_name, $excluded_facet_names, true ) ) {
+		$excluded_facet_names = apply_filters( 'facetwp_a11y_excluded_facet_names', [] );
+		if ( in_array( $facet_name, $excluded_facet_names, true ) ) {
 			return $html;
 		}
 
@@ -217,12 +219,12 @@ public function facetwp_add_labels( string $html, array $args ): string {
 		}
 
 		// Return default HTML if these facets are empty
-		$excluded_empty_facets = [
+		$excluded_empty_facets = apply_filters( 'facetwp_a11y_excluded_empty_facets', [
 			'checkboxes',
 			'pager',
 			'reset',
-		];
-		if ( true === in_array( $args['facet']['type'], $excluded_empty_facets, true ) && empty( $args['values'] ) ) {
+		] );
+		if ( in_array( $args['facet']['type'], $excluded_empty_facets, true ) && empty( $args['values'] ) ) {
 			return $html;
 		}