@@ -249,6 +249,26 @@ public function setActiveFromUri($uri)
249249
250250 // if languages set
251251 if ($ this ->enabled ()) {
252+ // Check for explicit language override via ?lang= query parameter.
253+ // This allows switching to any language (including the default language
254+ // when include_default_lang is false and the URL has no language prefix).
255+ $ requestedLang = $ _GET ['lang ' ] ?? null ;
256+ if ($ requestedLang ) {
257+ $ requestedLang = strtolower ($ requestedLang );
258+ if (in_array ($ requestedLang , $ this ->languages , true )) {
259+ $ this ->setActive ($ requestedLang );
260+
261+ // Store in session.
262+ if (isset ($ this ->grav ['session ' ]) && $ this ->grav ['session ' ]->isStarted ()
263+ && $ this ->config ->get ('system.languages.session_store_active ' , true )
264+ ) {
265+ $ this ->grav ['session ' ]->active_language = $ this ->active ;
266+ }
267+
268+ return $ uri ;
269+ }
270+ }
271+
252272 // Try setting language from prefix of URL (/en/blah/blah).
253273 if (preg_match ($ regex , $ uri , $ matches )) {
254274 $ this ->lang_in_url = true ;
@@ -263,36 +283,22 @@ public function setActiveFromUri($uri)
263283 $ this ->grav ['session ' ]->active_language = $ this ->active ;
264284 }
265285 } else {
266- if ($ this ->config ->get ('system.languages.include_default_lang ' ) === false ) {
267- // When include_default_lang is false, the default language has no URL prefix.
268- // A URL without a language prefix IS the default language explicitly.
269- $ this ->setActive ($ this ->getDefault ());
270-
271- // Store in session if language is different.
272- if (isset ($ this ->grav ['session ' ]) && $ this ->grav ['session ' ]->isStarted ()
273- && $ this ->config ->get ('system.languages.session_store_active ' , true )
274- && $ this ->grav ['session ' ]->active_language != $ this ->active
275- ) {
276- $ this ->grav ['session ' ]->active_language = $ this ->active ;
277- }
278- } else {
279- // Try getting language from the session, else no active.
280- if (isset ($ this ->grav ['session ' ]) && $ this ->grav ['session ' ]->isStarted () &&
281- $ this ->config ->get ('system.languages.session_store_active ' , true )) {
282- $ this ->setActive ($ this ->grav ['session ' ]->active_language ?: null );
283- }
284- // if still null, try from http_accept_language header
285- if ($ this ->active === null &&
286- $ this ->config ->get ('system.languages.http_accept_language ' ) &&
287- $ accept = $ _SERVER ['HTTP_ACCEPT_LANGUAGE ' ] ?? false ) {
288- $ negotiator = new LanguageNegotiator ();
289- $ best_language = $ negotiator ->getBest ($ accept , $ this ->languages );
290-
291- if ($ best_language instanceof AcceptLanguage) {
292- $ this ->setActive ($ best_language ->getType ());
293- } else {
294- $ this ->setActive ($ this ->getDefault ());
295- }
286+ // Try getting language from the session, else no active.
287+ if (isset ($ this ->grav ['session ' ]) && $ this ->grav ['session ' ]->isStarted () &&
288+ $ this ->config ->get ('system.languages.session_store_active ' , true )) {
289+ $ this ->setActive ($ this ->grav ['session ' ]->active_language ?: null );
290+ }
291+ // if still null, try from http_accept_language header
292+ if ($ this ->active === null &&
293+ $ this ->config ->get ('system.languages.http_accept_language ' ) &&
294+ $ accept = $ _SERVER ['HTTP_ACCEPT_LANGUAGE ' ] ?? false ) {
295+ $ negotiator = new LanguageNegotiator ();
296+ $ best_language = $ negotiator ->getBest ($ accept , $ this ->languages );
297+
298+ if ($ best_language instanceof AcceptLanguage) {
299+ $ this ->setActive ($ best_language ->getType ());
300+ } else {
301+ $ this ->setActive ($ this ->getDefault ());
296302 }
297303 }
298304 }
0 commit comments