説明
Plone のプログラムによって言語の状態を参照、変更します。
それぞれのセッションでは言語に関連する情報を記載しています。
有効な言語は plone.i18n.negotiator モジュールによって 決定 されます。 以下のいくつかの要因によってどの言語を使用するかを決定します。
言語の決定についてはページを表示するときの最初にネゴシエーションを行います。
view/viewlet で現在の言語を取得する例です。
from Acquisition import aq_inner
from zope.component import getMultiAdapter
class MyView(BrowserView):
...
def language(self):
"""
@return: Two letter string, the active language code
"""
context = aq_inner(self.context)
portal_state = getMultiAdapter((context, self.request), name=u'plone_portal_state')
current_language = portal_state.language()
return current_language
全てのコンテンツトオブジェクトは IDublinCore インターフェースで定義されている Language() での検索をサポートしているわけではありません。 以下は、コンテンツが提供された言語を安全に取得する方法です。
BrowserView メソッドの例:
from Acquisition import aq_inner
def language(self):
""" Get the language of the context.
Useful in producing <html> tag.
You need to output language for every HTML page, see http://www.w3.org/TR/xhtml1/#strict
@return: The two letter language code of the current content.
"""
portal_state = self.context.unrestrictedTraverse("@@plone_portal_state")
return aq_inner(self.context).Language() or portal_state.default_language()
Manually:
# Setup site langauge settings portal = context.getSite() ltool = portal.portal_languages defaultLanguage = 'en' supportedLanguages = ['en','es'] ltool.manage_setLanguageSettings(defaultLanguage, supportedLanguages, setUseCombinedLanguageCodes=False)
手動で行います。:
# サイトの言語設定を行います
portal = context.getSite()
ltool = portal.portal_languages
defaultLanguage = 'en'
supportedLanguages = ['en','ja']
ltool.manage_setLanguageSettings(defaultLanguage, supportedLanguages,
setUseCombinedLanguageCodes=False)
ユニットテストのために、言語の設定を変更したあとの afterSetUp() の中で以下のコードを実行する必要があります。:
# THIS IS FOR UNIT TESTING ONLY
# Normally called by pretraverse hook,
# but must be called manually for the unit tests
# Goes only for the current request
ltool.setLanguageBindings()
GenericSetup と propertiestool.xml を使用します。
Linguaplone が有効になっているサイトでは、 GenericSetup の portal_languages.xml を使用します。
多言語の plone サイトでは2種類の言語セレクター用の viewlet が存在します。
さらに情報を得るためには、以下を参照してください。
異なる言語のために複数ドメインを使用しているサイトでは、言語セレクターでそれぞれのドメインを遷移する方がよりよい場合があります。 検索エンジンは動的な言語の変更はうまく処理できず言語切り替えのリンクをインデックス化し、その結果あなたのサイトの検索結果として適切でないものを出力する場合があります。
例
以下のサンプルコードを参照してください。
languages.py:
"""
Custom language negotiator based on hostname.
"""
from Products.PloneLanguageTool import LanguageTool
# These are default languages available when hostname cannot be solved
all_languages = [ "fi", "en" ]
def get_host_name(request):
""" Extract host name in virtual host safe manner
@param request: HTTPRequest object, assumed contains environ dictionary
@return: Host DNS name, as requested by client. Lowercased, no port part.
"""
if "HTTP_X_FORWARDED_HOST" in request.environ:
# Virtual host
host = request.environ["HTTP_X_FORWARDED_HOST"]
elif "HTTP_HOST" in request.environ:
# Direct client request
host = request.environ["HTTP_HOST"]
else:
host = None
return host
# separate to domain name and port sections
host=host.split(":")[0].lower()
return host
def get_language(domain_name):
"""
@param domain_name: Full qualified domain name of HTTP request
"""
if domain_name.endswith(".mobi") or domain_name.endswith(".com"):
return "en"
elif domain_name.endswith(".fi"):
return "fi"
else:
return "en"
def getCcTLDLanguages(self):
"""
Monkey-patched top level domain language negotiator.
This will be installed by collective.monkeypatcher.
"""
if not hasattr(self, 'REQUEST'):
return None
request = self.REQUEST
# Could not extract hostname
hostname = get_host_name(request)
if not hostname:
return all_languages
# Limit available languages based on hostname
langs = [ get_language(hostname) ]
return langs
# Also we need to fix a bug present in Plone 3.3.5
#
# @memoize
# def language(self):
# # TODO Looking for lower-case language is wrong, the negotiator
# # machinery uses uppercase LANGUAGE. We cannot change this as long
# # as we don't ship with a newer PloneLanguageTool which respects
# # the content language, though.
# return self.request.get('language', None) or \
# aq_inner(self.context).Language() or self.default_language()
from plone.memoize.view import memoize, memoize_contextless
def working_portal_state_language(self):
return self.request.get('LANGUAGE', None) or \
self.request.get('language', None) or \
aq_inner(self.context).Language() or \
self.default_language()
working_portal_state_language = memoize(working_portal_state_language)
configure.zcml:
<!-- Use collective.monkeypatcher to introduce our custom language negotiation phase -->
<monkey:patch
description="Add custom TLD language resolution"
class="Products.PloneLanguageTool.LanguageTool"
original="getCcTLDLanguages"
replacement=".languages.getCcTLDLanguages"
/>
<monkey:patch
description="Fix Plone 3.3.5 bug"
class="plone.app.layout.globals.portal.PortalState"
original="language"
replacement=".languages.working_portal_state_language"
/>