Topic on Project:Support desk

Change the interface language for anonymous via JavaScript

5
Spas.Z.Spasov (talkcontribs)

Hello,

I'm tring to create a script that changes the MediaWiki interface language via javascript based on the page language at my private wiki.

For logged-in users I'm able to do that by changing the user's options via an API request as shown below, but this do not work for anonymous users. So my question is: Is it possible to change the interface language for anonymous users/visitors via JavaScript? And how do I do that?

/**
 * Automatic switch of wgUserLanguage, based on wgPageContentLanguage
 * The output of Template:AutoLangSwitch (id='auto-lang-switch') is the triger
**/
( function ( $, mw ) {
	mw.loader.using( 'mw.Api' ).then( function () {
		var nsNumber = mw.config.get( 'wgNamespaceNumber' );
		var lgAction = mw.config.get( 'wgAction' );
		var pageLang = mw.config.get( 'wgPageContentLanguage' );
		var userLang = mw.config.get( 'wgUserLanguage' );
		var langTest = document.getElementById( 'auto-lang-switch' );
		
		if ( pageLang !== userLang && lgAction === 'view' && nsNumber === 0 && langTest ) {
			var params = {
				action: 'options',
				change: 'language=' + pageLang,
				format: 'json'
			},
			api = new mw.Api();
			api.postWithToken( 'csrf', params ).done( function ( data ) {
				console.log( data );
			} );
			location.reload();
		}
	} );
}( jQuery, mediaWiki ) );
TheDJ (talkcontribs)
Spas.Z.Spasov (talkcontribs)

Hi, @TheDJ, thank you for the replay and the shared script! I was thinking about the possibility to use the parameter ?uselang=xx (like it is made in Gadget-AnonymousI18N.js), but I found this solution too complicated.

Finally I found a simple way how to engage Extension:UniversalLanguageSelector for this task. ULS writes two cookies: _language=xx and _mwuser-sessionId=xxyyzz. All we need in order to solve the current task is to set the language cookie and reload the page. So, for anonymous users the script could be:

/**
 * Automatic switch of wgUserLanguage, based on wgPageContentLanguage 
 * by the help of Extension:ULS
 * The output of Template:AutoLangSwitch (id='auto-lang-switch') is the triger
**/
( function ( $, mw ) {
	var nsNumber = mw.config.get( 'wgNamespaceNumber' );
	var lgAction = mw.config.get( 'wgAction' );
	var pageLang = mw.config.get( 'wgPageContentLanguage' );
	var userLang = mw.config.get( 'wgUserLanguage' );
	var langTest = document.getElementById( 'auto-lang-switch' );
	
	if ( pageLang !== userLang && lgAction === 'view' && nsNumber === 0 && langTest ) {
		mw.cookie.set('language', pageLang);
		location.reload();
	}
}( jQuery, mediaWiki ) );

According to that the final script that works for logged-in and anonymous users is:

/**
 * Automatic switch of wgUserLanguage, based on wgPageContentLanguage 
 * by the help of Extension:ULS and mw.Api
 * The output of Template:AutoLangSwitch (id='auto-lang-switch') is the triger
 */
( function ( $, mw ) {
	var userId    = mw.config.get( 'wgUserId' );
	var nsNumber  = mw.config.get( 'wgNamespaceNumber' );
	var lgAction  = mw.config.get( 'wgAction' );
	var pageLang  = mw.config.get( 'wgPageContentLanguage' );
	var userLang  = mw.config.get( 'wgUserLanguage' );
	var cookLang  = mw.cookie.get('language');
	var allowedNS = [0, 1, 4, 5, 14, 15];
	var langTest  = document.getElementById( 'auto-lang-switch' );

	// Logged-in users
	if ( pageLang !== userLang && lgAction === 'view' && userId !== null && allowedNS.includes(nsNumber) && langTest ) {
		mw.loader.using( 'mw.Api' ).then( function () {
			var params = {
				action: 'options',
				change: 'language=' + pageLang,
				format: 'json'
			},
			api = new mw.Api();
			api.postWithToken( 'csrf', params ).done( function ( data ) {
				console.log( data );
			} );
			location.reload();
		} );
	} else // Anonymous users
	if ( pageLang !== userLang && lgAction === 'view' && userId === null && cookLang !== pageLang && allowedNS.includes(nsNumber) && langTest ) {
		var sessionId = mw.cookie.get( 'mwuser-sessionId');
		if ( sessionId ) {
			console.log('mwuser-sessionId: ' + sessionId);
		} else {
			sessionId = mw.user.generateRandomSessionId();
			mw.cookie.set( 'mwuser-sessionId', sessionId, { expires: null } );
		}
		
		mw.cookie.set('language', pageLang); 
		location.reload();
	}
}( jQuery, mediaWiki ) );
TheDJ (talkcontribs)

Just make sure you vary cache on the cookie header for anonymous users in that case, otherwise people might get unexpected results from proxies.

Spas.Z.Spasov (talkcontribs)

Thank you for the help, @TheDJ. I've added mw.cookie.set( 'mwuser-sessionId', sessionId) in the script above.

Reply to "Change the interface language for anonymous via JavaScript"