Language Namespace
++language++ namespace
Status
Author
Problem/Proposal
Sometimes it would be useful to request pages in the language which is different from the browser preferred language.
By default the browser preferred language is requested from the HTTP_ACCEPT_LANGUAGE environment variable. But in some cases it would be useful to override this settings through the URL, like this:
http://site.com/++language++ru/path
Use cases:
- Some user agents (for example mobile phones) doesn't allow user to set the browser preferred language;
- It would be helpful for sites with selectable languages;
- Debuging sites with i18n pages;
Proposed Solution
Add new traversal adapter for ++language++ namespace.
After small discussion of the proposal we found two main ways to implement the adapter:
1) The simplest way. We just modify the request's HTTP_ACCEPT_LANGUAGE
variable like this:
class language(object):
implements(ITraversable)
def __init__(self, context, request):
self.context = context
self.request = request
def traverse(self, name, ignored):
self.request.shiftNameToApplication()
self.request._environ["HTTP_ACCEPT_LANGUAGE"] = name
return self.context
The main problems with this approach (as pointed by Philipp)
is what the protected (underscored) read-only attribute _environ
modified by an external object and we also don't want to lose
the initial value of the variable.
2) Philipp suggested that the ++language++ namespace handler uses
a some way of annotating the request with the language data, which
is then may be extracted by a special IUserPreferredLanguages adapter.
Stephan also pointed out what the locale of the request is created
upon instantiation using HTTPRequest.__setupLocale() method. So the
method should be called after any changes in the language data.
Philipp think that the name ++language++ is quite long and suggested
use ++lang++ instead but we already have ++resource++ so I don't think
what it worth it.
So conclude I propose the following solution:
- Add new interface (and also an adapter for IHTTPRequest? interface):
class IModifiableUserPreferredLanguages(IUserPreferredLanguages): def setPreferredLanguages(languages): """Set a sequence of user preferred languages. The sequence should be sorted in order of quality, with the most preferred languages first. """ - Rename
HTTPRequest.__setupLocale()method tosetupLocale()and specify the new method in theIHTTPRequestinterface.
Risks
The IModifiableUserPreferredLanguages interface/adapter already
implemented on the hdima-language-namespace branch. Also the language
data is now cached so the HTTP_ACCEPT_LANGUAGE variable parsed only
one time.
Another potential risk --philikon, 2005/08/07 15:51 EST reply
The (IMO rightful) introduction of IModifiableUserPreferredLanguages bares another risk. Imagine this scenario:
- The default
IModifiableUserPreferredLanguagesadapter is enabled. - A developer familiar with Zope X3 and 3.1 wishes to override language behaviour, so he registers his own
IUserPreferredLanguagesadapter over the default one. - Code that wants to extract preferred languages will adapt the request to
IUserPreferredLanguages, invoking the custom adapter. - The
++language++namespace handler will adapt the request toIModifiableUserPreferredLanguageswhich yields the default adapter. - The result is that
++language++will not work as expected because the two adapter lookups don't match.
In general, the situation described above is no drama. It should just be documented well enough so that people know how to make ++language++ work again (I'm thinking of docstrings in IModifiableUserPreferredLanguages and the language namespace handler and a good entry in CHANGES.txt).
As for ++lang++ vs. ++language++, you say that we already have ++resource++ which is pretty long also. That is of course correct; however, ++resource++ is almost never exposed to the visitor of a site (it is usually used in PageTemplates? to traverse to a Resource object) whereas ++language++ might very well be exposed to the visitor through the URL. Of course, I don't feel strongly about this point. I can very much live with ++language++, I just want to save some typing... :)
Another potential risk --hdima, 2005/08/11 06:19 EST reply
You're right, moreover the setPreferredLanguages method will change the request locale. But I think the setPreferredLanguages method should just check for the request annotations which should be set at the time when the request is created only if compatible adapter has been used or raise an error if no annotations has been found.
And '++lang++'wins... :)
