Forum Discussion

mdfw's avatar
mdfw
Genius
2 years ago

Set the visitor UI language automatically

Background:

  1. Our instance supports 8 different languages for the user interface.
  2. Our CDN/Reverse Proxy detects a user's location and can set a user's language based on that. It will, at a minimum, set a cookie.
  3. In the past, in the page.init, we would detect if the cookie language was different than the session language and and return a redirect while adding the "?profile.language=xx" parameter. Unfortunately, this caused significant delays for users in China because of the extra round trip.
  4. Currently our CDN/reverse proxy rewrites all URLs as they pass through, adding the profile.language parameter to *every* page load. This causes some odd side-effects, especially in the admin panel. It's also very challenging to debug when something is off.

 

Does anyone know the recommended approach to making sure that a user (including anonymous users) gets the Khoros page UI in their translated language? Our CDN/reverse proxy does place a cookie that we can read or it could deliver a special header. I imagine we could read this in page.init, but I don't see anywhere in the docs where we can tell the session to switch languages. 

This all gives hints:

Other related threads I have read:

 

Thanks!

Mark

  • IanKl's avatar
    IanKl
    Khoros Alumni (Retired)

    It's a little harder to implement automatically, but you could probably more easily do a dropdown that sets a registered user's preference, but to persist an anonymous user's preferences, you'd have to get Khoros support to turn on 

    enable.PersistentAnonymousUserSettings = true

    in your config.js file.  

    If you want to get a parameter from the url, since your CDN/rp rewrites everything, you can use

    https://developer.khoros.com/khoroscommunitydevdocs/reference/url

     to get the url and use the freemarker ?index_of to find what you're looking for in the string,

    https://freemarker.apache.org/docs/ref_builtins_string.html#ref_builtin_index_of 

    for example, though a bit messy because it's in longhand, it'll work:

     

    <#assign myUrl = "http://somewebsite.com/purple/my/lang/cues/en/hello-there"/>
    <#assign myLangStart = myUrl?index_of("my/lang/cues/") />
    <#assign myLangEnd = myLangStart+1 />
    <#assign myLang = myUrl[myLangStart..myLangEnd] />
    
    
    myUrl: ${myUrl}
    myLangStart; ${myLangStart}
    myLangEnd: ${myLangEnd}
    myLang: ${myLang}

     

     

    And then set the language via modifying the user setting through the API. I'll find the link for you tomorrow. 

  • IanKl's avatar
    IanKl
    Khoros Alumni (Retired)

    Ok, final answer, I believe, you need the following to set the user profile lanugage:

    <#assign userLang = "fr" /> <#-- or whatever you want it to be -->
    <#assign resp = restadmin("/users/id/${user.id?c}/settings/name/profile.language/set?value=" + userLang?url)/>

     Unfortunately, the documentation for setting the profile.language (or really, any setting) does not include the critical last part of the correct API call, 

    https://community.yoursite.com/restapi/vc/users/id/[user_id]/settings/name/[setting_name]/set?value=[language_id]?url  

    or, for example, 

    https://community.khoros.com/restapi/vc/users/id/1234/settings/name/profile.language/set?value=fr?url 

    where?url indicates that it should be url encoded.

    Ok, hope that all answers your question enough for you to get a working solution. If not, mdfw just tag me here and I'll try to help some more 

    - Ian

  • A little excerpt from the code docs of my own Khoros framework as we are dealing with multilanguage communities every day:

     

    The cookie interesting to us regarding language logic is `lia.anon.profile.language` which stores the community-wide language setting for anonymous users and is set and changed whenever the URL parameter `?profile.language=<lang>` is provided, although
    this only happens when the ancient config `enable.PersistentAnonymousUserSettings = true` is set (has to be requested from support, not true by default!). This automatically
    set cookie is a common source of issues, as the cookie is only written when a user is NOT logged in! We can take care of that by updating the cookie manually right after the language is set via REST API for an authenticated user.
    
    A custom cookie + attributes can be created and set in the page init script like follows:
    
    ```
    	<#assign cookie = http.request.createCookie('<cookiename>', '<cookievalue>') />
    	${cookie.setMaxAge(365*24*60*60)}
    	${cookie.setDomain('.domain.com')}
    	${cookie.setPath('/')}
    	${cookie.setValue('your cookie value')}
    	${cookie.setHttpOnly(true)}
    	${cookie.setSecure(true)}
    	${cookie.setComment('Describes what this cookie does')}
    	${http.response.addCookie(cookie)}
    ```
    
    and be checked with `${http.request.cookies.name.get('<cookiename>')}`.

     

     

    Key takeaway here is to use that cookie lia.anon.profile.language and use it as the main source of "language-truth" AND keep it updated when a user is logged in and changes languages. Keeping it up-to-date is also important to KEEP the logged-in language when a user logs out, because if the logged-in language differs from the value of the cookie, the user will experience a "nice" language switch when logging out 😉

  • IanKl's avatar
    IanKl
    Khoros Alumni (Retired)

    Good question. I've done something like this before on another community, but I'm not sure if it would be considered "best practice." I have a question out to my peers about this and I'll be back soon with a better answer. I'm looking into this.

  • IanKl's avatar
    IanKl
    Khoros Alumni (Retired)

    On this page, there is a url param that supposedly changes the profile language, though I haven't so far been able to get it to work on the sites I tested.

    https://community.khoros.com/t5/Community-display/Languages-that-Khoros-Communities-support/ta-p/6566

    • Add ?profile.language=KEY as a parameter to any URL in your community (where KEY is the language code listed on the page above).

    Would you give this a shot on your community to see if it works? 

  • IanKl's avatar
    IanKl
    Khoros Alumni (Retired)

    Good question mdfw  I was hoping the ?profile.language=xx hack would solve that but I have not seen it work on a Community yet. Did it work on yours?

    In the meantime I will look into whether we can change a setting like that for a default user and get back to you. 

    • mdfw's avatar
      mdfw
      Genius

      It's interesting IanKl - I swear the profile.language worked before as we signed off on the current implementation but just had a colleague in Costa Rica test it and it didn't work. So, I may have 2 problems now. 🙂 I'll get some more tests done to see if we can narrow it down.

      Regardless, I'd like replace it with something, just don't know what that something is.

      • IanKl's avatar
        IanKl
        Khoros Alumni (Retired)

        Make sure the folks in Costa Rica are logged out before trying the

        ?profile.language=xx

        parameter. 

        What luk added also looks very helpful. 

        How are things coming along with this?

  • IanKl's avatar
    IanKl
    Khoros Alumni (Retired)

    Ok, mdfw  https://forums.ni.com/?profile.language=zh-CN (for example) does work on your community, and according to everything I can find, the only way to set a language for an anonymous user is by setting this url parameter. 

    So I would use the combination of tricks I mentioned above (probably starting with a cookie) to let the community know to change the language in the url for this user. As far as I can tell so far, that's your only option for anonymous users. 

    So, on load just check if there's a cookie with the languageValue value, if so, something like (pseudocode, use whatever cookie code style you prefer😞

    if(cookie exists with value = langaugeValue){
      window.location = yoururl + "?profile.language="+languageValue
    }

    if not drop a cookie for next time

    set a cookie = "languageValue=XX; expires=whatever date; path=/";