From 4be39296d6da74caf3b4b591d2255b16f332d906 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Tue, 21 Nov 2023 13:58:37 +0000 Subject: [PATCH] MDL-80185 lang: use iso6391 language code for HTML lang attributes. This resolves accessibility issues where Moodle language pack codes didn't always map to correspondingly named iso6391 codes. Where this value is defined in the language configuration, it will now be used. --- lib/classes/output/language_menu.php | 2 +- lib/tests/weblib_test.php | 5 +++-- lib/weblib.php | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/classes/output/language_menu.php b/lib/classes/output/language_menu.php index 7f9ba9b6490..b6a0fbc63e0 100644 --- a/lib/classes/output/language_menu.php +++ b/lib/classes/output/language_menu.php @@ -151,7 +151,7 @@ class language_menu implements \renderable, \templatable { if ($langparam) { $attributes = [ 'data-lang' => $langparam, - 'lang' => $langparam, + 'lang' => get_html_lang_attribute_value($langparam), ]; } $lang = new \action_menu_link_secondary($node['url'], null, $node['title'], $attributes); diff --git a/lib/tests/weblib_test.php b/lib/tests/weblib_test.php index f34b81e5066..342459b8420 100644 --- a/lib/tests/weblib_test.php +++ b/lib/tests/weblib_test.php @@ -1163,9 +1163,10 @@ EXPECTED; */ public function get_html_lang_attribute_value_provider() { return [ - 'Empty lang code' => [' ', 'unknown'], + 'Empty lang code' => [' ', 'en'], 'English' => ['en', 'en'], - 'English, US' => ['en_us', 'en-us'], + 'English, US' => ['en_us', 'en'], + 'Unknown' => ['xx', 'en'], ]; } diff --git a/lib/weblib.php b/lib/weblib.php index ec421819584..a0e16f3b906 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -2297,11 +2297,19 @@ function highlightfast($needle, $haystack) { * @return string */ function get_html_lang_attribute_value(string $langcode): string { - if (empty(trim($langcode))) { - // If the language code passed is an empty string, return 'unknown'. - return 'unknown'; + $langcode = clean_param($langcode, PARAM_LANG); + if ($langcode === '') { + return 'en'; } - return str_replace('_', '-', $langcode); + + // Grab language ISO code from lang config. If it differs from English, then it's been specified and we can return it. + $langiso = (string) (new lang_string('iso6391', 'core_langconfig', null, $langcode)); + if ($langiso !== 'en') { + return $langiso; + } + + // Where we cannot determine the value from lang config, use the first two characters from the lang code. + return substr($langcode, 0, 2); } /** -- 2.43.0