Page MenuHomePhabricator

Allow unauthenticated users to directly change language on the platform
Open, MediumPublic

Description

We currently localise the platform for unauthenticated users based on their browser language settings, with no option to change the language within the platform. We do however support explicit language change for authenticated users, but only after navigating to the user profile.

Ideally, we should allow users (both logged in and not) to change the interface language from wherever they are.

Ideally - this would take the form of a dropdown option in the site navigation bar. If the user is not logged in, then this can just take effect for the duration of the user's session. If they are logged in, it should update their user profile language preference.

Event Timeline

Something on the lines of the attached image (from inventaire.io) would be good

image.png (570×223 px, 37 KB)

If possible, can I work on this issue?

Sure! I don't have a lot of guidance on _how_ to work on this, but let me know if you have any questions about what we're looking for.

@Samwalton9 Really sorry for the late response! Can we use the same language translation drop-down menu on the nav-bar for users, that has been used in the preferences section of the user page? (The black outlined area in the attached image, which has been taken from https://wikipedialibrary.wmflabs.org/users/)
Or do we have to make it like the one @AVasanth_WMF mentioned (from inventaire.io)?

If we can use the former, then I assume we will have to put it on the navbar of all pages, right?

language-preferences.png (937×1 px, 81 KB)

Also, I seem to be unable to login on localhost. Whenever I click login, I get an error screen which says:

IntegrityError at /oauth/callback/
(1062, "Duplicate entry '64010842' for key 'username'")

I tried finding out where this error is coming from, but couldn't find anything that could have caused this. A possible origin seems be the _get_and_update_user_from_identity function at /TWLight/users/oauth.py, line 138, but I don't exactly know how is that causing the error.

Please help me out here. I am attaching a screenshot of the error and a link to the traceback.

error.png (942×1 px, 144 KB)

Can we use the same language translation drop-down menu on the nav-bar for users, that has been used in the preferences section of the user page?

I think that would be fine, it doesn't need to be as complicated as the inventaire example. It would need to behave differently though, because that dropdown changes the user's stored profile data - we would want this to also work for logged-out users.

Whenever I click login, I get an error screen

That's strange - try clearing out your database and starting from scratch.

Samwalton9 renamed this task from Allow unauthenticated users to explicitly change language on the platform to Allow unauthenticated users to directly change language on the platform.Sep 9 2021, 11:52 AM
Samwalton9 updated the task description. (Show Details)

Yes, please feel free. This might be a bit of a bigger project to work on, and as always please let me know if you need assistance :)

This comment was removed by Ajay47.

Hello @Samwalton9, I have some questions and suggestions regarding this task

First of all, I found a bug in production regarding user preferred language. When a user logs in to TWlight and changes his/her preferred language to anything for example, to Deutsch. So we want the Deutsch should become his/her default profile language for their entire session as well as for their next login. But When the user logs in next time the default language doesn’t take effect and the user’s profile is set to English again.
The same will happen if the user logs in from some other device.

We can complete this task as described in the description but that will cause another bug. If the user changes his/her language before login, for example to Deutsch. After that, there are two cases:
  1. The user doesn’t log in so the language only takes effect during the session.
  2. User logs into TWlight then Deutsch will become his default profile language.

But this causes an issue. If the user visits the site again and logs in without changing the language to Deutsch, then English (which is the default for our website) will become his default profile language.

One solution for this is that we allow users to change the language from the homepage but that should only take effect until the user logs in. But when the user logs in he can set their default profile language and this will take effect every time the user logs in to TWlight.

First of all, I found a bug in production regarding user preferred language. When a user logs in to TWlight and changes his/her preferred language to anything for example, to Deutsch. So we want the Deutsch should become his/her default profile language for their entire session as well as for their next login. But When the user logs in next time the default language doesn’t take effect and the user’s profile is set to English again.
The same will happen if the user logs in from some other device.

That's strange. I can't reproduce this. I go to production (https://wikipedialibrary.wmflabs.org/), change my language to Deutsch, log out (I see the homepage in German now), log back in and I still see the site in German and my user preference is still set to German.

Is there something else I can do to reproduce this error?

If the user changes his/her language before login, for example to Deutsch. After that, there are two cases

This is a really great overview of the problem - thanks for taking the time to write it out.

One solution for this is that we allow users to change the language from the homepage but that should only take effect until the user logs in. But when the user logs in he can set their default profile language and this will take effect every time the user logs in to TWlight.

I think it would make sense that if a new user changes their language on the homepage, then we should assume they want to use the site in that language and therefore we update their profile to set this as their default language. But for editors who already have an account, we should just use their profile language and not overwrite it. So the behaviour should be like this, for example:

  • A new user visits the site with their browser language in English, so the homepage defaults to English. They don't change their language and log in. Their profile has their default language set to English.
  • A new user visits the site with their browser language in English, so the homepage defaults to English. They change their language to German and log in. Their profile sets their default language to German.
    • The user logs out, then returns to the site with their browser language still in English, so the homepage defaults to English. They don't change their language and log in. We don't overwrite their profile language, which was German, so we still show the site in German once logged in.

Then we should still have a language selector when logged in, and this should update your default language setting and reload the page.

Does that make sense?

Thank you for your insights :) I am sharing some more thoughts on this

Is there something else I can do to reproduce this error?

following these steps will help you to reproduce this
login → change your language to Deutsch → open the site in incognito/in some other browser then your current browser/ in your smartphone and login again you will see the language set to Deutsch in your profile but everything else will be in the English language.

A new user visits the site with their browser language in English, so the homepage defaults to English. They change their language to German and log in. Their profile sets their default language to German.

To make this happen let’s say we apply a trigger on each login
whatever user’s homepage language before login → make that user’s default language and set it to user’s profile after login.

The user logs out, then returns to the site with their browser language still in English, so the homepage defaults to English. They don't change their language and log in. We don't overwrite their profile language, which was German, so we still show the site in German once logged in.

Now in this scenario also the trigger I previously set will run again after the user logs in.
So this time when the homepage language is English before login, that will make the default language English after login.

To prevent this I was thinking about keeping the 2 actions separate i.e. having no relation between language selected before login and after login.
Whatever language they choose on the homepage before login we can set it to their browser cookie.
And whatever language they choose post login we will save that in our User/Editor model and will keep that persistent over all sessions.

So basically the language they see after login should only be changed if they change their language from the profile section (after login).

following these steps will help you to reproduce this

Oh. You're right, I've just reproduced this, thanks for the steps. Strange that no one else has reported this in the past. I've filed T291474, but appreciate we might fix both issues in this task.

So basically the language they see after login should only be changed if they change their language from the profile section (after login).

I was thinking that if a user chooses to change their language on the homepage, they probably want their profile to update to this language too for future visits. But that's probably more complicated to implement, so I agree that starting with your proposed implementation is a great first step.

To prevent this I was thinking about keeping the 2 actions separate i.e. having no relation between language selected before login and after login.
Whatever language they choose on the homepage before login we can set it to their browser cookie.
And whatever language they choose post login we will save that in our User/Editor model and will keep that persistent over all sessions.
So basically the language they see after login should only be changed if they change their language from the profile section (after login).

This sounds great, let's start here and maybe we can make it more complicated like I suggested afterwards :)

I've filed T291474, but appreciate we might fix both issues in this task

I will try to implement both in the way we have discussed :)

Thanks for the PR @Ajay47! Some thoughts from testing this out locally:

  • The language selector is quite cramped into the corner, can you pad it out a little?
  • I do feel like the behaviour is a bit confusing when the user has some other language preference on Wikipedia or their profile. In my case, I selected French on the homepage, logged in, and by the time I was on My Library I was back in English because that's my user profile setting. Could it be the case that when a user chooses a language (and you set the cookie), that when they log in their user preference is updated to that language automatically? If the user changes their language on the homepage I assume they want to change it elsewhere too. From a quick uneducated glance at the code it looks like you're explicitly setting the cookie when the user submits the form, so this could avoid the issue of overwriting a preference accidentally.

Sure, I will make changes and update PR soon. Thank you.

@Ajay47 How are things? Do you need any support with this?

Hello @Samwalton9, Sorry for the late response. I made all changes as requested but I am facing a little issue. When user change their language from the homepage that will persist after login but I can't store that in the userprofile's lang field. This cause problem when user login with defferent device/browser. That time if user login without changing language from homepage, their langauge set to langauge that they set from langauge section after login in last visit. Can you tell me how I can save that language in lang field? I think one possible solution can be use of signal that called everytime user login, but I can't find which signal I can use for this purpose. Thank you.

@Ajay47 there are a few things to keep in mind here:
The view that processes the setlang form posts does different things based on the user session at submission time. You are showing this form when a user is logged out, so there is no is no userprofile to save things to.
There is a cookie that gets set by set_language() in the form response, and that's one of the things that get_language() checks.
In your PR you've created a new language form and view and left the existing language stuff alone.
To get these two different cases (authenticated and anonymous) working, the behavior of the existing language code needs to be updated in the user app.
I recommend using a common form and view for the setting the language and update to accommodate both cases.
When logged in, you'll need to check to see if user.userprofile.lang is different from get_language() and update the userprofile if they differ.
This is actually the only purpose of our custom i18n.views.set_language() function, so I think that whole function could be dropped if you are handling in the view code for the selection form itself.

Right now your language form only shows up on the front page for anonymous users. It should really also be showing up in the other header templates as well.

Thank you :). I updated the PR. If there is anything needs to be changed let me know.