LinguaPlone は各フィールドが言語に依存するか、非依存かのマークをつけることが可能です。
ノート
Example:
try: from Products.LinguaPlone import public as atapi except ImportError: # No multilingual support from Products.Archetypes import atapi class MyContent(atapi.ATContent): pass atapi.registerType(MyContent, ...)
例:
try:
from Products.LinguaPlone import public as atapi
except ImportError:
# No multilingual support
from Products.Archetypes import atapi
class MyContent(atapi.ATContent):
pass
atapi.registerType(MyContent, ...)
より詳細な情報は以下を参照してください。
考えられるユースケース
ITranslatable.getTranslation() メソッドを使用することにより、現在の言語で翻訳されたコンテンツを表示することができます。
- def getTranslation(language=’language’):
- “”” Return the object corresponding to a translated version or None. If called without arguments it returns the translation in the currently selected language, or self. “”“
Example:
class Footer(BaseViewlet): """ A footer viewlet which will pull editable and translated footer text. The localized text is available as Archetypes Page object which id is "footer-text" in the site root. LinguaPlone translation look-up is performed. 1. Create the footer in your site main language as a hidden Page which id is set to "footer-text" 2. Use "Translate to..." action to create localized versions of this footer 3. Leave footer private so that it does not appear in the search results etc. Note that the workflow state of the footer content is not considered. Note that "footer" is reserved id in Plone, thus we use "footer-text". """
例:
class Footer(BaseViewlet):
""" A footer viewlet which will pull editable and translated footer text.
The localized text is available as Archetypes Page object which id
is "footer-text" in the site root. LinguaPlone translation look-up
is performed.
1. Create the footer in your site main language as a hidden
Page which id is set to "footer-text"
2. Use "Translate to..." action to create localized versions
of this footer
3. Leave footer private so that it does not appear in the
search results etc.
Note that the workflow state of the footer content is not considered.
Note that "footer" is reserved id in Plone, thus we use "footer-text".
"""
grok.name("plone.footer")
grok.viewletmanager(IPortalFooter)
def getFooterText(self):
""" Call this from your viewlet template.
Example::
<div id="portal-footer">
<div tal:replace="structure viewlet/getFooterText" />
</div>
"""
from Products.LinguaPlone.interfaces import ITranslatable
portal = self.portal_state().portal()
if "footer-text" in portal.objectIds(): # Note that you can use has_key() for BTree based folders
footer = portal["footer-text"]
if ITranslatable.providedBy(footer):
translated = footer.getTranslation()
if translated:
return translated.getText()
return footer.getText()
return ""
LinguaPlone は翻訳を作成する方法を参照するための、ユニットテスト用のコードを含んでいます。 context.addTranslation(言語コード) メソッドと context.getTranslation(言語コード) メソッドを使用することができます。
例:
from Products.LinguaPlone.I18NBaseObject import AlreadyTranslated
try:
object.addTranslation(lang)
except AlreadyTranslated:
# 備考: Products.Linguaplone がインストールされていない場合は、常に AlreadyTranslated が発生します
pass
translated = object.getTranslation(lang)
http://svn.plone.org/svn/plone/LinguaPlone/tags/2.1.1/Products/LinguaPlone/tests/translate_edit.txt を参照して下さい。
以下のような場合に適用されます。
SEO とユーザビリティ上の理由により、一定のドメインからは必ず一定のコンテンツが提供されなければいけません。 ユーザーが日本語ドメインの /news や逆に英語ドメインの /oshirase コンテクストにアクセスすることを、Plone は防ぐことができません。 これらの URL がサーチエンジンに漏れた場合、混乱の原因となります。
以下のような複雑な publication 後のフック処理により、ユーザーの要求に対してその言語で提供すべき正しいドメインに対してリダイレクトします。:
"""
Domain aware language redirects.
Redirect the user to a correct domain where the language should be served,
if mixing and matching different domain names and language versions.
http://mfabrik.com
"""
import urlparse
from zope.interface import Interface
from zope.component import adapter, getUtility, getMultiAdapter
from plone.postpublicationhook.interfaces import IAfterPublicationEvent
from gomobile.mobile.utilities import get_host_domain_name
from gomobile.mobile.interfaces import IMobileRequestDiscriminator, MobileRequestType
from Products.CMFCore.interfaces import IContentish
def get_contentish(object):
"""
Traverse acquisition upwards until we get contentish object used for the HTTP response.
"""
contentish = object
while not IContentish.providedBy(contentish):
if hasattr(contentish, "aq_parent"):
contentish = contentish.aq_parent
else:
break
return contentish
def redirect_domain(request, response, new_domain):
""" Redirect user to a new domain, but having URI in intact.
This also keeps port part of netloc in intact.
@param new_domain: New domain name to redirect, without port.
"""
# Get the
url = request["ACTUAL_URL"]
parts = urlparse.urlparse(url)
# Replace domain name
parts = list(parts)
netloc = parts[1]
# TODO: Handle @ and HTTP Basic auth here
if ":" in netloc:
domain, port = netloc.split(":")
netloc = new_domain + ":" + port
else:
netloc = new_domain
parts[1] = netloc
new_url = urlparse.urlunparse(parts)
# Make 301 Permanent Redirect response
response.redirect(new_url, status=301)
response.body = ""
response.setHeader("Content-length", 0)
def ensure_in_domain(request, response, language_now, wanted_language, wanted_domain):
""" Make sure that certain language gets served from a correct domain.
If the user tries to access URI of page, and the page language
does not match the domain we expect, redirect the user to the correct domain.
"""
domain_now = get_host_domain_name(request)
if language_now == wanted_language:
if domain_now != wanted_domain:
# print "Fixing language " + language_now + " to go to " + wanted_domain + " from " + domain_now
redirect_domain(request, response, wanted_domain)
@adapter(Interface, IAfterPublicationEvent)
def language_fixer(object, event):
""" Redirect mobile users to mobile site using gomobile.mobile.interfaces.IRedirector.
Note: Plone does not provide a good hook doing this before traversing, so we must
do it in post-publication. This adds extra latency, but is doable.
"""
# print "language_fixer"
request = event.request
response = request.response
context = get_contentish(object)
if hasattr(context, "Language"):
# Check whether the context has a Language() accessor to get
# the language where it was written in
language_now = context.Language()
#print "Resolving mobility"
discriminator = getUtility(IMobileRequestDiscriminator)
flags = discriminator.discriminate(context, request)
if MobileRequestType.MOBILE in flags:
# Do mobile
ensure_in_domain(request, response, language_now, "fi", "m.mfabrik.fi")
ensure_in_domain(request, response, language_now, "en", "mfabrik.mobi")
else:
# Do web
ensure_in_domain(request, response, language_now, "fi", "mfabrik.fi")
ensure_in_domain(request, response, language_now, "en", "mfabrik.com")
# print "Done"