support for other languages in newov
I am playing around with newov and especially freeform. It is very nice. Since I need to support German at my web site it would nice if error messages and other information that are sent back to the visitor could be in an other language. I came up with a simple solution using a dict that holds all the messages in different languages. multilang.py multilangDict = {'emptyPasswd':{'eng':"Please enter a non-empty password.", 'de':"Ein leeres Passwort ist nicht erlaubt. Eingabe bitte wiederholen!" }, 'passwdDontMatch':{'eng':"Passwords do not match. Please reenter.", 'de':"Die Passwörter stimmen nicht überrein. Eingabe bitte wiederholen!" } } Umlauts (ö and ü) work with my browser settings but might need to use & uml; notation: multilang2.py from newov stan import xml multilangDict = {'emptyPasswd':{'eng':"Please enter a non-empty password.", 'de':"Ein leeres Passwort ist nicht erlaubt. Eingabe bitte wiederholen!" }, 'passwdDontMatch':{'eng':"Passwords do not match. Please reenter.", 'de':xml("Die Passw¨rter stimmen nicht æuuml;berrein. Eingabe bitte wiederholen!") } } Unicode might be necessary if languages like Chinese are needed. in freeform.py you just put: from nevow import multilang multilangDict = multilang.multilangDict lang = 'de' #read from configuration somewhere or set by visitor or url like www.example.com/mylang/foo and change the formless.InputError arguments to dict lookups, e.g.: class PasswordValidator(components.Adapter): __implements__ = IInputValidator, def validate(self, context, boundTo, data): """Password needs to look at two passwords in the data, """ pw1 = data[0] if pw1 == '': raise formless.InputError(multilangDict['emptyPasswd'][lang]) #changed args = context.locate(iwoven.IRequest).args binding = context.locate(formless.IBinding) pw2 = args.get("%s____2" % binding.name, [''])[0] if pw1 != pw2: raise formless.InputError(multilangDict['passwdDontMatch'][lang]) #changed f return self.original.coerce(data[0]) This works the way I want it. Since the number of messages is rather small a dict seems ok in terms of memory usage. Because the languages part is in a separate file, it can be maintained by anybody who knows the (foreign) languages without the need of looking through the code. If the same message is used at several places changing it becomes much easier too. How do you thing about it? Mike
Mike Mueller [Thu, Jan 15, 2004 at 05:02:29AM +0100]:
I came up with a simple solution using a dict that holds all the messages in different languages. [...] How do you thing about it?
It's really nice. Any particular reasons you didn't use gettext? Just that I didn't know that it exists. Well, I didn't look for it. After looking at it, the problem is that gettext assumes that there is a global language that is valid for the the whole application at any given
At 09:02 15.01.2004 +0100, Michal wrote: point in time. I would like to have two (or more) languages at the same time. Depending on the preferred language of the current visitor, each session has "its" language. Even with my approach, using the lang attribute on the module level, will not work if asynchronous programming is involved. Since I am going to use deferreds, time is 'not linear any more'. So changing the lang attribute of a module back and forth might have effects on different sessions(?) A solution would be to make the lang a session attribute: At the first encounter of the session do: request = context.locate(iwoven.IRequest) session = request.getSession() lang = getattr(session, 'lang', currentLang) later you might want to change the language: request = context.locate(iwoven.IRequest) session = request.getSession() session.lang = currentLangNow Extend the relevant parts of freeform.py (and other modules that return messages) to: class PasswordValidator(components.Adapter): __implements__ = IInputValidator, def validate(self, context, boundTo, data): """Password needs to look at two passwords in the data, """ request = context.locate(iwoven.IRequest) session = request.getSession() pw1 = data[0] if pw1 == '': raise formless.InputError(multilangDict['emptyPasswd'][session.lang]) #changed args = context.locate(iwoven.IRequest).args binding = context.locate(formless.IBinding) pw2 = args.get("%s____2" % binding.name, [''])[0] if pw1 != pw2: raise formless.InputError(multilangDict['passwdDontMatch'][session.lang]) #changed return self.original.coerce(data[0]) This should give you the possibility to guess the language from request.getHeader('user-agent') and also let the visitor to select his/her preferred languages (you know those small icons with flags). I don't know if this is the best way to do it. If yes, is there any way that it makes it into the source? It would essentially mean adding this two lines to all the methods that return some kind of message to the visitor, provided all of the relevant methods take a context argument. And of course it means using multilangDict['phraseKey'][session.lang] instead of a message English message consistently . I would volunteer to implement this and could also make the German messages. Mike
Mike Mueller wrote:
At 09:02 15.01.2004 +0100, Michal wrote:
It's really nice. Any particular reasons you didn't use gettext?
Just that I didn't know that it exists. Well, I didn't look for it. After looking at it, the problem is that gettext assumes that there is a global language that is valid for the the whole application at any given point in time. I would like to have two (or more) languages at the same time. Depending on the preferred language of the current visitor, each session has "its" language.
You sure about that? I'm certain I remember a conversation where someone else said the same thing, but was successfully told otherwise (with an explanation). I don't remember the details, but maybe someone else does (or you'll notice them if you look deeper ;) -- Twisted | Christopher Armstrong: International Man of Twistery Radix | Release Manager, Twisted Project ---------+ http://radix.twistedmatrix.com/
Mike : After looking at it, the problem is that gettext assumes that there is a global language that is valid for the the whole application at any given point in time. I would like to have two (or more) languages at the same time. Depending on the preferred language of the current visitor, each session has "its" language.
Christopher (radix): You sure about that? I'm certain I remember a conversation where someone else said the same thing, but was successfully told otherwise (with an explanation). I don't remember the details, but maybe someone else does (or you'll notice them if you look deeper ;)
Do you mean gettext is not global for whole application or it is not possible to store the language in a session? I guess the latter. This boils down to problems with unique session data. In the December archive of twisted-web I found <http://www.twistedmatrix.com/pipermail/twisted-web/2003-December/000045.html>http://www.twistedmatrix.com/pipermail/twisted-web/2003-December/000045.html which a essentially says, as long as session data are always retrieved from request and ./twistd -oy script.tac is used it should work. I hope this applies to newov. Getting session straight is very important if people need to have different views on a page. This is a rather common scenario for dynamic pages, I think. Mike
participants (3)
-
Christopher Armstrong
-
Michal Pasternak
-
Mike Mueller