By querying the portal_languages tool I can get a list of language names:
>>> from Products.CMFPlone.utils import getToolByName
>>> ltool = getToolByName(context, 'portal_languages')
>>> language_names = [name for code, name in ltool.listAvailableLanguages()]
[u'Abkhazian', u'Afar', u'Afrikaans', u'Albanian', u'Amharic', (...)
But how can I return a list of localized language names?
[EDIT] What I want is the list of language names in the language 开发者_Python百科of the current user, as shown in @@language-controlpanel See: http://i.imgur.com/rGfjG.png
If you want translated language names in many different languages, install Babel (http://pypi.python.org/pypi/Babel). There's good documentation on it, for example http://packages.python.org/Babel/display.html:
>>> from babel import Locale
>>> locale = Locale('de', 'DE').languages['ja']
u'Japanisch'
Plone only includes native and English language names. The zope.i18n package has some of this data, but it's really incomplete and outdated, so Babel is your best bet.
Use the listAvailableLanguageInformation()
method instead:
>>> from Products.CMFPlone.utils import getToolByName
>>> ltool = getToolByName(context, 'portal_languages')
>>> native_language_names = [entry[u'native']
... for entry in ltool.listAvailableLanguageInformation()]
[u'Afrikaans', u'Aymara', u'Az\u0259ri T\xfcrk\xe7\u0259si', u'Bahasa Indonesia', ...]
Note that the @@language-controlpanel view uses the zope.i18n.locales
module to provide translated languages; but that list is so incomplete that the languages list is not translated for most of UI languages. Apparently italian is one language where this is translated.
You can reach the locales structure via the request, or via the @@plone_state
view. The locales.displayNames.languages
dictionary maps language code (2 letters) to local language name:
>>> from Products.CMFPlone.utils import getToolByName
>>> ltool = getToolByName(context, 'portal_languages')
>>> languages = request.locales.displayNames.languages
>>> language_names = [languages.get(code, name) for code, name in ltool.listAvailableLanguages()]
[u'abkhazian', u'afar', u'afrikaans', u'albanese', u'amarico', ...]
As you can see, the language names are lowercased, not properly capitalized. Also, the data is expensive to parse (the package contains XML files parsed on first access) so it can take several moments before this data is available to you on first access.
Your best bet would be to use Babel, as Hanno states, as it actually has far more current information available, and not just for a handful of languages.
Thanks to Martijn's help I was able to solve the issue. This is the final working code that will generate the dictionary of translated language names. Very useful if you want to make a localized selection field such as the one found in the language control-panel.
from Products.CMFCore.interfaces import ISiteRoot
from zope.component import getMultiAdapter
from zope.site.hooks import getSite
from zope.globalrequest import getRequest
@grok.provider(IContextSourceBinder)
def languages(context):
"""
Return a vocabulary of language codes and
translated language names.
"""
# z3c.form KSS inline validation hack
if not ISiteRoot.providedBy(context):
for item in getSite().aq_chain:
if ISiteRoot.providedBy(item):
context = item
# retrieve the localized language names.
request = getRequest()
portal_state = getMultiAdapter((context, request), name=u'plone_portal_state')
lang_items = portal_state.locale().displayNames.languages.items()
# build the dictionary
return SimpleVocabulary(
[SimpleTerm(value=lcode, token=lcode, title=lname)\
for lcode, lname in lang_items]
)
精彩评论