From d6a0991e9753ab997ce00d559c76f6ecedfa3697 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 11 May 2026 12:53:23 +0700 Subject: [PATCH 1/9] fix: setLocaleFromURL * make regex case-insensitive * assign fallback locale --- _includes/locale/Locale.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/_includes/locale/Locale.php b/_includes/locale/Locale.php index 5792fd81..890d2ded 100644 --- a/_includes/locale/Locale.php +++ b/_includes/locale/Locale.php @@ -69,13 +69,14 @@ public static function invalidLocale() { */ private static function setLocaleFromURL() { // First component of the URL is always the locale - if(preg_match('/^\\/(([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?)\\//', $_SERVER['REQUEST_URI'], $matches)) { - if(!isset(DISPLAY_NAMES[$matches[1]])) { + if(preg_match('/^\/(([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?)\//i', $_SERVER['REQUEST_URI'], $matches)) { + $fallbackLocales = self::calculateFallbackLocales($matches[1]); + if (isset($fallbackLocales[0])) { + $pageLocale = $fallbackLocales[0]; + } else { // Note: this is an unsupported locale, so we'll end up redirecting in head.php to /en/... $pageLocale = Locale::DEFAULT_LOCALE; self::$invalidLocale = true; - } else { - $pageLocale = $matches[1]; } } else { $pageLocale = Locale::DEFAULT_LOCALE; From 7696ef1163085b1dffb97145627214232a9a8368 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 13 May 2026 14:30:15 +0700 Subject: [PATCH 2/9] Update _includes/locale/Locale.php --- _includes/locale/Locale.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/locale/Locale.php b/_includes/locale/Locale.php index 890d2ded..1d4e24d2 100644 --- a/_includes/locale/Locale.php +++ b/_includes/locale/Locale.php @@ -69,7 +69,7 @@ public static function invalidLocale() { */ private static function setLocaleFromURL() { // First component of the URL is always the locale - if(preg_match('/^\/(([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?)\//i', $_SERVER['REQUEST_URI'], $matches)) { + if(preg_match('/^\/(([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?)\//', $_SERVER['REQUEST_URI'], $matches)) { $fallbackLocales = self::calculateFallbackLocales($matches[1]); if (isset($fallbackLocales[0])) { $pageLocale = $fallbackLocales[0]; From 98d57af676445b7433e05af02cb9fceeb260cc87 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 13 May 2026 14:45:15 +0700 Subject: [PATCH 3/9] Update .htaccess bcp-47 regex * make case-sensitive * fix capitalization of Script and Region --- .htaccess | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/.htaccess b/.htaccess index f54bc722..9e521a62 100644 --- a/.htaccess +++ b/.htaccess @@ -395,8 +395,7 @@ RewriteRule "^(downloads/releases|keyboards)/(.+)$" "en/$1/$2" [R,L] # # Intentionally not using regex from Validation::validate_bcp47 because we only need lang-script-region triplet -# ^(([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?) -# [NC] for case-insensitive +# ^(([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?) # Long regex for "BCP-47" codes = $1, rest of URL $2 onward # @@ -405,26 +404,26 @@ RewriteRule "^(downloads/releases|keyboards)/(.+)$" "en/$1/$2" [R,L] # # /keyboards/install/[id] to /keyboards/install.php -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/install/([^/]+)$" "/_content/keyboards/install.php?id=$2" [END,QSA] # /keyboards/download/[id] to /keyboards/keyboard.php # This formerly redirected to a download, but we no longer need it; keep it for # legacy links -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/download/([^/]+)$" "/_content/keyboards/keyboard.php?id=$2" [END,QSA] # /keyboards/share/[id] to /keyboards/share.php # if the keyboard exists in the repo, then share.php will redirect to /keyboards/ -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/share/([^/]+)$" "/_content/keyboards/share.php?id=$2" [END,QSA] # /keyboards/{id}.json to /keyboards/keyboard.json.php -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/(?!keyboard.json)(.*)\.json$" "/_content/keyboards/keyboard.json.php?id=$2" [END] # /keyboards/{id} to /keyboards/keyboard.php -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/(?!index\.php|install|keyboard|session|share)([^/]+)$" "/_content/keyboards/keyboard.php?id=$2" [END,QSA] # @@ -432,23 +431,23 @@ RewriteRule "^([^/]+)/keyboards/(?!index\.php|install|keyboard|session|share)([^ # # /keyboards/languages to /keyboards/index.php -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/languages/(.*)" "/_content/keyboards/index.php?q=l:id:$2" [END,QSA] # /keyboards/download to /keyboards/download.php -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/download(.php)?" "/_content/keyboards/download.php" [END,QSA] # /keyboards/legacy to /keyboards/keyboard.php -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/legacy/(.*)" "/_content/keyboards/keyboard.php?legacy=$2" [END] # /keyboards/countries to /keyboards/index.php -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards/countries/(.*)" "/_content/keyboards/index.php?q=c:id:$2" [END] # Root keyboard search to pass embed query? -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/keyboards(/)?$" "/_content/keyboards/index.php" [END,QSA] @@ -457,10 +456,10 @@ RewriteRule "^([^/]+)/keyboards(/)?$" "/_content/keyboards/index.php" [END,QSA] # # /contact/exception to /contact/exception.php -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/contact/exception(.php)?$" "/_content/contact/exception.php" [END,QSA] -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/contact/exception\?id=(.+)$" "/_content/contact/exception?id=$2" [END] # @@ -469,16 +468,16 @@ RewriteRule "^([^/]+)/contact/exception\?id=(.+)$" "/_content/contact/exception? # releases-tier/download # note: the tier is currently ignored -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/downloads/releases/(alpha|beta|stable)/(.+)$" "/_content/downloads/releases/_version_downloads.php?tier=$2&version=$3" [END] # releases-download -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/downloads/releases/(.+)$" "/_content/downloads/releases/_version_downloads.php?version=$2" [END] # other file types RewriteCond "%{DOCUMENT_ROOT}/_content/$2" -f -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/(.+)$" "/_content/$2" [END] # TODO: do we want en/lao --> en/keyboards/basic_kbdlao? as well as /lao --> ... @@ -493,32 +492,32 @@ RewriteRule "^([^/]+)/(.+)$" "/_content/$2" [END] # Rewrite file to file.md RewriteCond "%{DOCUMENT_ROOT}/_content/$2.md" -f -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/(.+)$" "/_includes/includes/md/mdhost.php?file=_content/$2.md" [END] # Rewrite file to file.php RewriteCond "%{DOCUMENT_ROOT}/_content/$2.php" -f RewriteCond "%{DOCUMENT_ROOT}/_content/$2.md" !-f -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/(.+)$" "/_content/$2.php" [END] # Rewrite folder/ to folder/index.md RewriteCond "%{DOCUMENT_ROOT}/_content/$2/index.md" -f -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/(.+)/$" "/_includes/includes/md/mdhost.php?file=_content/$2/index.md" [END] # Rewrite folder/ to folder/index.php RewriteCond "%{DOCUMENT_ROOT}/_content/$2/index.php" -f RewriteCond "%{DOCUMENT_ROOT}/_content/$2/index.md" !-f -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/(.+)/$" "/_content/$2/index.php" [END] # Root page -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)/$" "/_content/index.php" [END] # Finally, append the terminating slash for folders, given it is no longer # done automatically because we put DirectorySlash off, for the top-level paths only RewriteCond "%{DOCUMENT_ROOT}/_content/$2$3" -d -RewriteCond "$1" ^([a-z]{2,3})(-([A-Za-z]{4}))?(-([a-z]{2}|[0-9]{3}))?$ [NC] # BCP 47 match +RewriteCond "$1" ^([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?$ RewriteRule "^([^/]+)(.*)([^/])?$" "$1$2$3/" [R,QSA] From a262260f1bfe31c505a3e4584d0b862f600ec080 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 13 May 2026 14:53:18 +0700 Subject: [PATCH 4/9] invalidate locale if regex fails --- _includes/locale/Locale.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_includes/locale/Locale.php b/_includes/locale/Locale.php index 1d4e24d2..25bfae20 100644 --- a/_includes/locale/Locale.php +++ b/_includes/locale/Locale.php @@ -79,7 +79,9 @@ private static function setLocaleFromURL() { self::$invalidLocale = true; } } else { + // Invalid locale $pageLocale = Locale::DEFAULT_LOCALE; + self::$invalidLocale = true; } self::setLocale($pageLocale); } From e291fc48f26daff2b80a7fc96ea2414ab5cc2058 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Wed, 13 May 2026 15:50:02 +0700 Subject: [PATCH 5/9] revert invalidating locale --- _includes/locale/Locale.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_includes/locale/Locale.php b/_includes/locale/Locale.php index 25bfae20..3c0d36be 100644 --- a/_includes/locale/Locale.php +++ b/_includes/locale/Locale.php @@ -79,9 +79,8 @@ private static function setLocaleFromURL() { self::$invalidLocale = true; } } else { - // Invalid locale $pageLocale = Locale::DEFAULT_LOCALE; - self::$invalidLocale = true; + // Don't set invalid locale so pages like /_test/ work } self::setLocale($pageLocale); } From 058eb1173fd72510077b0dbbb2a31e4c5009b2f9 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 14 May 2026 09:37:30 +0700 Subject: [PATCH 6/9] fix: additional fallback fixes * revert some .htacess.in to allow optional script/region * fix globe key to handle fallback locales and where tag is missing in the original path --- _includes/2020/templates/Menu.php | 10 ++++++---- _includes/locale/Locale.php | 3 ++- build.sh | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/_includes/2020/templates/Menu.php b/_includes/2020/templates/Menu.php index c6cdf1b6..63c7540c 100644 --- a/_includes/2020/templates/Menu.php +++ b/_includes/2020/templates/Menu.php @@ -35,7 +35,7 @@ public static function render(array $fields): void { /** * Modify link of the current URL for a given UI language. - * Skip if current URL isn't localized (e.g. _legacy) + * If current URL isn't localized (e.g. _legacy or no BCP-47 in path), return original URL * @param language - language tag to use * @return string - modified URL */ @@ -45,12 +45,14 @@ private static function change_ui_language($language): string { $parts = parse_url($url); $path = ''; - // Replace language if current language in path is valid BCP-47 + // Replace $path[1] if a fallback locale of $language is in DISPLAY_NAMES if (!empty($parts['path'])) { $path = explode("/", $parts['path']); - if ($path[1] == Locale::pageLocale()) { + $matchingLanguages = isset($path[1]) ? + array_intersect(Locale::calculateFallbackLocales($path[1]), array_keys(DISPLAY_NAMES)) : []; + if (count($matchingLanguages) > 0) { $path[1] = $language; - } else if (preg_match('/^\/(_legacy)\/.*$/i', $path[1], $matches)) { + } else if (preg_match('/^(?!_legacy)([^\/]+)$/i', $path[1], $matches)) { // original URL didn't have a valid BCP-47, so insert new langage // Skip for certain paths like: _legacy array_splice($path, 1, 0, $language); diff --git a/_includes/locale/Locale.php b/_includes/locale/Locale.php index ad3cafba..cc240310 100644 --- a/_includes/locale/Locale.php +++ b/_includes/locale/Locale.php @@ -72,6 +72,7 @@ private static function setLocaleFromURL() { $fallbackLocales = self::calculateFallbackLocales($matches[1]); if (isset($fallbackLocales[0])) { $pageLocale = $fallbackLocales[0]; + self::$invalidLocale = false; } else { // Note: this is an unsupported locale, so we'll end up redirecting in head.php to /en/... $pageLocale = Locale::DEFAULT_LOCALE; @@ -180,7 +181,7 @@ public static function definePageScope($define, $id) { * @param $locale - the locale to determine fallback locales * @return array of fallback locales */ - private static function calculateFallbackLocales($locale) { + public static function calculateFallbackLocales($locale) { // Start with the given locale $fallback = [$locale]; diff --git a/build.sh b/build.sh index 09a113d6..6db57502 100755 --- a/build.sh +++ b/build.sh @@ -38,7 +38,7 @@ function preprocess_htaccess() { local locales localesregex locales=($(cat ./_includes/locale/locales.json | grep '"' | cut -d\" -f 2 -)) localesregex=$(IFS=\| ; echo "${locales[*]}") - sed -e "s/@locales/${localesregex}/g" .htaccess.in >> .htaccess + sed -e "s/(@locales)/(([a-z]{2,3})(-([A-Z][a-z]{3}))?(-([A-Z]{2}|[0-9]{3}))?)/g" .htaccess.in >> .htaccess } function do_configure() { From b06e7e8246726aea85279b4b021cce189f1f2a66 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 14 May 2026 09:57:35 +0700 Subject: [PATCH 7/9] expand list of paths not to insert tag --- _includes/2020/templates/Menu.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_includes/2020/templates/Menu.php b/_includes/2020/templates/Menu.php index 63c7540c..04c7c40a 100644 --- a/_includes/2020/templates/Menu.php +++ b/_includes/2020/templates/Menu.php @@ -52,9 +52,9 @@ private static function change_ui_language($language): string { array_intersect(Locale::calculateFallbackLocales($path[1]), array_keys(DISPLAY_NAMES)) : []; if (count($matchingLanguages) > 0) { $path[1] = $language; - } else if (preg_match('/^(?!_legacy)([^\/]+)$/i', $path[1], $matches)) { + } else if (preg_match('/^(?!_legacy|go|mac|web)([^\/]+)$/i', $path[1], $matches)) { // original URL didn't have a valid BCP-47, so insert new langage - // Skip for certain paths like: _legacy + // Skip for certain paths like: _legacy or 2-3 letter paths array_splice($path, 1, 0, $language); } } From f04a525e096e671e8cf44ce738a6f42004e4cf1d Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 14 May 2026 10:40:10 +0700 Subject: [PATCH 8/9] chore: cleanup comments --- _includes/locale/Locale.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_includes/locale/Locale.php b/_includes/locale/Locale.php index cc240310..d9bb999c 100644 --- a/_includes/locale/Locale.php +++ b/_includes/locale/Locale.php @@ -72,7 +72,6 @@ private static function setLocaleFromURL() { $fallbackLocales = self::calculateFallbackLocales($matches[1]); if (isset($fallbackLocales[0])) { $pageLocale = $fallbackLocales[0]; - self::$invalidLocale = false; } else { // Note: this is an unsupported locale, so we'll end up redirecting in head.php to /en/... $pageLocale = Locale::DEFAULT_LOCALE; @@ -80,7 +79,7 @@ private static function setLocaleFromURL() { } } else { $pageLocale = Locale::DEFAULT_LOCALE; - // Don't set invalid locale so pages like /_test/ work + // Don't set invalidLocale so pages like /_test/ work } self::setLocale($pageLocale); } From 182723f6e969da76ca7144012739f81422c34f72 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 14 May 2026 11:00:55 +0700 Subject: [PATCH 9/9] handle redirecting locales --- _includes/2020/templates/Head.php | 5 +---- _includes/locale/Locale.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/_includes/2020/templates/Head.php b/_includes/2020/templates/Head.php index 769a9294..4c4cb9ae 100644 --- a/_includes/2020/templates/Head.php +++ b/_includes/2020/templates/Head.php @@ -39,10 +39,7 @@ static function render($fields = []) { // Redirect to /en/... if not a supported locale; this needs to be emitted // as a HTTP header before first content byte. if(Locale::invalidLocale()) { - if(preg_match('/^\\/[^\/]+\\/(.+)$/', $_SERVER['REQUEST_URI'], $matches)) { - header("Location: /" . Locale::DEFAULT_LOCALE . "/" . $matches[1]); - return; - } + Locale::redirectLocale(); } ?> diff --git a/_includes/locale/Locale.php b/_includes/locale/Locale.php index d9bb999c..6dedab63 100644 --- a/_includes/locale/Locale.php +++ b/_includes/locale/Locale.php @@ -62,6 +62,17 @@ public static function invalidLocale() { return self::$invalidLocale; } + /** + * Redirect page to specified locale. Default to en + * @param $newLocale + */ + public static function redirectLocale($newLocale = Locale::DEFAULT_LOCALE) { + if(preg_match('/^\\/[^\/]+\\/(.+)$/', $_SERVER['REQUEST_URI'], $matches)) { + header("Location: /" . $newLocale . "/" . $matches[1]); + return; + } + } + /** * Set the current locale based on the first path component * //rest/of/path for the current page URL @@ -72,6 +83,10 @@ private static function setLocaleFromURL() { $fallbackLocales = self::calculateFallbackLocales($matches[1]); if (isset($fallbackLocales[0])) { $pageLocale = $fallbackLocales[0]; + if ($pageLocale != $matches[1]) { + // Redirect if using a fallback locale + Locale::redirectLocale($pageLocale); + }; } else { // Note: this is an unsupported locale, so we'll end up redirecting in head.php to /en/... $pageLocale = Locale::DEFAULT_LOCALE;