Skip to content
Open
5 changes: 1 addition & 4 deletions _includes/2020/templates/Head.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
?><!DOCTYPE html>
<html lang='<?=$fields->pageLocale?>'>
Expand Down
12 changes: 7 additions & 5 deletions _includes/2020/templates/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -45,14 +45,16 @@ 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|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);
}
}
Expand Down
27 changes: 22 additions & 5 deletions _includes/locale/Locale.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,39 @@ 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
* /<locale>/rest/of/path for the current page URL
*/
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-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];
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;
self::$invalidLocale = true;
} else {
$pageLocale = $matches[1];
}
} else {
$pageLocale = Locale::DEFAULT_LOCALE;
// Don't set invalidLocale so pages like /_test/ work
}
self::setLocale($pageLocale);
}
Expand Down Expand Up @@ -178,7 +195,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];

Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
Loading