Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #2255 (closed defect: fixed)

Opened 10 years ago

Last modified 10 years ago

Language support in session lacking

Reported by: aigarius Owned by: jon
Priority: normal Milestone: 2.0rc1
Component: TurboGears Version: trunk
Severity: normal Keywords: i18n
Cc:

Description

The i18n support in TG2 is good, but one simple thing is lacking - saving language in a session. When we have an i18n'ed application and we have user sessions, then we should be able to allow users to change their desired language regardless of their browser setting. There is a  Pylons document about that, but the example provided does not work, because the before method of the RootController? is not being executed.

It would be very helpful if TG2 could look at the session and set a language from session's 'lang' parameter if such exists, overriding the browser accepted languages. This could be done in tg/controllers.py:setup_i18n() (assuming it gets called for every request).

After that we could switch languages by calling: pylons.sessionlang? = ru pylons.session.save() pylons.i18n.set_lang('ru')

As an alternatve a new function tg.set_lang() could be provided that would do the above to wrap it all up neatly.

Change History

comment:1 Changed 10 years ago by mramm

We need to fix the before method in the root controller, and there's a seprate ticket for that. Beyond that, it would be awesome if there were docs for this. The state of our internationalization docs are woefully inadequate at the moment. :(

comment:2 Changed 10 years ago by aigarius

The following did work when put into project/lib/base.py

class BaseController(TGController):

    def __before__( self, *args ):
        if 'beaker.session' in request.environ and 'lang' in request.environ['beaker.session']:
            set_lang(request.environ['beaker.session']['lang'])

Adding this trick to the i18n documentation could be very useful.

comment:3 Changed 10 years ago by aigarius

Ok, I was too hasty. The code get's executed, but the set_lang does not take effect for some reason - the templates show up not translated.

comment:4 Changed 10 years ago by jon

  • Status changed from new to assigned
  • Owner set to jon
  • Version changed from 2.0b6 to 2.0b7

This problem is due to the fact setup_i18n (run in _perfom_call phase) is overriding the lang you've set (this function is checking to see what is the best language for the UA). We need to add that session support for i18n in the core, in that function (if a lang is found in session, set it and don't override it)...

About the session key name, I think it should be configurable (and not just 'lang' or 'tg_lang').

I'll try to see how to implement that today.

comment:5 Changed 10 years ago by jon

Tentative fix in [6489]. Still to do : create tests and docs for this i18n.py.

To make use of it, import set_lang from tg.i18n, and add this in your root controller :

    @expose()
    def set_lang(self, previous_url, lang):
        """set the desired language in the session and
        redirect to the previous url

        @param previous_url: the url the visit is coming from
        @type previous_url: string

        @param lang: the desired locale of type: 'en', or such 
        @type lang: string
        """
        set_lang(lang)
        redirect(previous_url)

comment:6 Changed 10 years ago by kikidonk

  • Version changed from 2.0b7 to trunk

I quickly glanced at the patch, but there is still something i want to be able to do, but can't currently.

I would like the language to be setup in the user cookie instead of a server-side session. That means the setup_i18n() should also look for a cookie to set the current request language.

This calls for a better extensibility of the setup_i18n stuff. It should probably be a method of TGController so that it can be overridden in the $project.lib.base.BaseController? on a per-project basis to add cookie support/session support and even routes support if need be.

As a workaround I had to monkey patch the setup_i18n function to add my cookie handling code in there, while with subclassing i would have just added the cookie check before or after the current code.

comment:7 Changed 10 years ago by mramm

  • Milestone changed from 2.0rc1 to 2.1

Sure, that makes sense. But I think we have to bite the bullet here and get 2.0 out the door, so I'm going to assign the rest of this to 2.1

comment:8 Changed 10 years ago by aigarius

  • Status changed from assigned to closed
  • Resolution set to fixed

Looks fixed for me with r6489

comment:9 Changed 10 years ago by aigarius

Some code for kicks.

    @expose()
    def set_lang(self, lang='en', came_from = "/"):
        session = request.environ['beaker.session']
        session['tg_lang'] = lang
        session.save()
        set_lang( lang )
        flash( _('Language changed to English.') ) #This nessage is translated to other languages ;)
        redirect( came_from )

Actually works for me in TG2 RC2.

comment:10 Changed 10 years ago by aigarius

Actually re-reading r6489 , it is perfectly sufficient to just call tg.i18n.set_lang('en') . Good job!

comment:11 Changed 10 years ago by jorge.vargas

  • Milestone changed from 2.1 to 2.0rc1

This landed in 2.0 after all.

Note: See TracTickets for help on using tickets.