diff --git a/system/src/Grav/Common/Language/Language.php b/system/src/Grav/Common/Language/Language.php index 5390f1455..6f91500fc 100644 --- a/system/src/Grav/Common/Language/Language.php +++ b/system/src/Grav/Common/Language/Language.php @@ -240,6 +240,26 @@ class Language // if languages set if ($this->enabled()) { + // Check for explicit language override via ?lang= query parameter. + // This allows switching to any language (including the default language + // when include_default_lang is false and the URL has no language prefix). + $requestedLang = $_GET['lang'] ?? null; + if ($requestedLang) { + $requestedLang = strtolower($requestedLang); + if (in_array($requestedLang, $this->languages, true)) { + $this->setActive($requestedLang); + + // Store in session. + if (isset($this->grav['session']) && $this->grav['session']->isStarted() + && $this->config->get('system.languages.session_store_active', true) + ) { + $this->grav['session']->active_language = $this->active; + } + + return $uri; + } + } + // Try setting language from prefix of URL (/en/blah/blah). if (preg_match($regex, $uri, $matches)) { $this->lang_in_url = true; @@ -254,36 +274,22 @@ class Language $this->grav['session']->active_language = $this->active; } } else { - if ($this->config->get('system.languages.include_default_lang') === false) { - // When include_default_lang is false, the default language has no URL prefix. - // A URL without a language prefix IS the default language explicitly. - $this->setActive($this->getDefault()); + // Try getting language from the session, else no active. + if (isset($this->grav['session']) && $this->grav['session']->isStarted() && + $this->config->get('system.languages.session_store_active', true)) { + $this->setActive($this->grav['session']->active_language ?: null); + } + // if still null, try from http_accept_language header + if ($this->active === null && + $this->config->get('system.languages.http_accept_language') && + $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? false) { + $negotiator = new LanguageNegotiator(); + $best_language = $negotiator->getBest($accept, $this->languages); - // Store in session if language is different. - if (isset($this->grav['session']) && $this->grav['session']->isStarted() - && $this->config->get('system.languages.session_store_active', true) - && $this->grav['session']->active_language != $this->active - ) { - $this->grav['session']->active_language = $this->active; - } - } else { - // Try getting language from the session, else no active. - if (isset($this->grav['session']) && $this->grav['session']->isStarted() && - $this->config->get('system.languages.session_store_active', true)) { - $this->setActive($this->grav['session']->active_language ?: null); - } - // if still null, try from http_accept_language header - if ($this->active === null && - $this->config->get('system.languages.http_accept_language') && - $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? false) { - $negotiator = new LanguageNegotiator(); - $best_language = $negotiator->getBest($accept, $this->languages); - - if ($best_language instanceof AcceptLanguage) { - $this->setActive($best_language->getType()); - } else { - $this->setActive($this->getDefault()); - } + if ($best_language instanceof AcceptLanguage) { + $this->setActive($best_language->getType()); + } else { + $this->setActive($this->getDefault()); } } }