Commit cc21d8c1 authored by Yusei Tahara's avatar Yusei Tahara

Commit content translation feature.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@30269 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 36c5a052
......@@ -26,41 +26,67 @@
#
##############################################################################
from Base import func_code, ATTRIBUTE_PREFIX, evaluateTales, Getter as BaseGetter
from zLOG import LOG
from Products.ERP5Type.PsycoWrapper import psyco
from Acquisition import aq_base
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Accessor.Base import func_code, ATTRIBUTE_PREFIX, evaluateTales, Getter as BaseGetter
from Products.ERP5Type.Accessor import Accessor, AcquiredProperty
from Products.ERP5Type.Accessor.TypeDefinition import type_definition
TRANSLATION_DOMAIN_CONTENT_TRANSLATION = 'content_translation'
class TranslatedPropertyGetter(BaseGetter):
"""
Get the translated property
"""
_need__name__=1
# This can be called from the Web
func_code = func_code()
func_code.co_varnames = ('self', )
func_code.co_varnames = ('self',)
func_code.co_argcount = 1
func_defaults = ()
def __init__(self, id, key, warning=0):
def __init__(self, id, key, property_id, property_type, language, default=None, warning=0):
self._id = id
self.__name__ = id
self._key = key
self._original_key = key.replace('translated_', '')
self._property_id = property_id
self._null = type_definition[property_type]['null']
self._language = language
self._default = default
self._warning = warning
def __call__(self, instance, *args, **kw):
if self._warning:
LOG("ERP5Type Deprecated Getter Id:",0, self._id)
domain = instance.getProperty('%s_translation_domain' %
self._original_key)
value = instance.getProperty(self._original_key)
domain = instance.getProperty('%s_translation_domain' % self._property_id)
if domain==TRANSLATION_DOMAIN_CONTENT_TRANSLATION:
if len(args) > 0:
default = args[0]
else:
default = self._default
if self._language is None:
language = kw.get('language') or getToolByName(instance, 'Localizer').get_selected_language()
else:
language = self._language
try:
return instance.getPropertyTranslation(self._property_id, language)
except KeyError:
return default
else:
value = instance.getProperty(self._property_id)
if domain == '' or (value in ('', None)):
return value
localizer = getToolByName(instance, 'Localizer')
return localizer[domain].gettext(unicode(value, 'utf8')).encode('utf8')
message_catalog = getattr(localizer, domain, None)
if message_catalog is not None:
return message_catalog.gettext(unicode(value, 'utf8'), lang=self._language).encode('utf8')
else:
return value
psyco.bind(__call__)
......@@ -80,9 +106,7 @@ class PropertyTranslationDomainGetter(BaseGetter):
def __init__(self, id, key, property_type, default=None, storage_id=None):
self._id = id
self.__name__ = id
self._key = key
self._original_key = key.replace('_translation_domain', '')
self._property_type = property_type
self._default = default
if storage_id is None:
storage_id = "%s%s" % (ATTRIBUTE_PREFIX, key)
......@@ -126,3 +150,68 @@ class PropertyTranslationDomainGetter(BaseGetter):
psyco.bind(__call__)
class TranslationPropertySetter(Accessor.Accessor):
"""
Set a translation into language-property pair dict.
"""
_need__name__=1
# Generic Definition of Method Object
# This is required to call the method form the Web
# More information at http://www.zope.org/Members/htrd/howto/FunctionTemplate
func_code = func_code()
func_code.co_varnames = ('self', 'value')
func_code.co_argcount = 2
func_defaults = ()
def __init__(self, id, key, property_id, property_type, language):
self._id = id
self.__name__ = id
self._property_id = property_id
self._language = language
self._cast = type_definition[property_type]['cast']
self._null = type_definition[property_type]['null']
def __call__(self, instance, *args, **kw):
value = args[0]
modified_object_list = []
domain = instance.getProperty('%s_translation_domain' % self._property_id)
if domain==TRANSLATION_DOMAIN_CONTENT_TRANSLATION:
if value in self._null:
instance.deletePropertyTranslation(self._property_id, self._language)
else:
original_property_value = instance.getProperty(self._property_id)
instance.setPropertyTranslation(self._property_id, self._language, original_property_value, self._cast(args[0]))
modified_object_list.append(instance)
else:
pass
#raise RuntimeError, 'The property %s.%s is not writable.' % (instance.portal_type, self._property_id)
return modified_object_list
class AcquiredPropertyGetter(AcquiredProperty.Getter):
def __call__(self, instance, *args, **kw):
if len(args) > 0:
default = args[0]
else:
default = None
value = instance._getDefaultAcquiredProperty(self._key, None, self._null,
base_category=self._acquisition_base_category,
portal_type=self._acquisition_portal_type,
accessor_id=self._acquisition_accessor_id,
copy_value=self._acquisition_copy_value,
mask_value=self._acquisition_mask_value,
sync_value=self._acquisition_sync_value,
storage_id=self._storage_id,
alt_accessor_id=self._alt_accessor_id,
acquisition_object_id=self._acquisition_object_id,
is_list_type=self._is_list_type,
is_tales_type=self._is_tales_type,
checked_permission=kw.get('checked_permission', None)
)
if value is not None:
return value.getProperty(self._acquired_property, default, **kw)
else:
return default
......@@ -64,6 +64,7 @@ from Products.ERP5Type.Utils import createExpressionContext
from Products.ERP5Type.Accessor.Accessor import Accessor
from Products.ERP5Type.Accessor.TypeDefinition import list_types
from Products.ERP5Type.Accessor import Base as BaseAccessor
from Products.ERP5Type.mixin.property_translatable import PropertyTranslatableBuiltInDictMixIn
from Products.ERP5Type.XMLExportImport import Base_asXML
from Products.ERP5Type.Cache import CachingMethod, clearCache, getReadOnlyTransactionCache
from Accessor import WorkflowState
......@@ -711,7 +712,9 @@ class Base( CopyContainer,
PortalContent,
ActiveObject,
OFS.History.Historical,
ERP5PropertyManager ):
ERP5PropertyManager,
PropertyTranslatableBuiltInDictMixIn
):
"""
This is the base class for all ERP5 Zope objects.
It defines object attributes which are necessary to implement
......
......@@ -24,6 +24,9 @@ from Acquisition import aq_base, Implicit
import Products
from Products.ERP5Type.Accessor import Translation
from Products.CMFCore.utils import getToolByName
from zLOG import LOG
_MARKER = {}
......@@ -86,6 +89,23 @@ class TranslationProviderBase(object):
return dict((k, v.__of__(self))
for k, v in self._property_domain_dict.iteritems())
security.declarePublic('getContentTranslationDomainPropertyNameList')
def getContentTranslationDomainPropertyNameList(self):
result = []
for property_name, translation_information in self.getPropertyTranslationDomainDict().items():
if translation_information.getDomainName()==Translation.TRANSLATION_DOMAIN_CONTENT_TRANSLATION:
result.append(property_name)
return result
security.declarePublic('getTranslationDomainNameList')
def getTranslationDomainNameList(self):
return (['']+
[object_.id
for object_ in getToolByName(self, 'Localizer').objectValues()
if object_.meta_type=='MessageCatalog']+
[Translation.TRANSLATION_DOMAIN_CONTENT_TRANSLATION]
)
#
# ZMI methods
#
......@@ -105,13 +125,13 @@ class TranslationProviderBase(object):
t['domain_name'] = prop.getDomainName()
translation_list.append(t)
# get list of Localizer catalog, add 'empty' one for no traduction
catalog = self.getPortalObject().Localizer.objectIds() + ['']
# get a list of message catalogs and add empty one for no traduction and
# add another for content translation.
translation_domain_list = self.getTranslationDomainNameList()
return self._translation_form( self
, REQUEST
, translations = translation_list
, possible_domain_names=catalog
, possible_domain_names=translation_domain_list
, management_view='Translation'
, manage_tabs_message=manage_tabs_message
)
......
......@@ -211,6 +211,19 @@ def convertToUpperCase(key):
UpperCase = convertToUpperCase
def convertToLowerCase(key):
tmp = []
assert(key[0].isupper())
for i in key:
if i.isupper():
tmp.append('_')
tmp.append(i.lower())
else:
tmp.append(i)
return ''.join(tmp)
LowerCase = convertToLowerCase
def convertToMixedCase(key):
"""
This function turns an attribute name into
......@@ -919,6 +932,7 @@ def importLocalDocument(class_id, document_path = None):
if not m.has_key(name): m[name] = []
m[name].append(method)
m[name+'__roles__']=pr
return document_class, constructors
def initializeLocalRegistry(directory_name, import_local_method,
path_arg_name='path'):
......@@ -1317,7 +1331,8 @@ def setDefaultProperties(property_holder, object=None, portal=None):
'%s_range_%s' % (prop['id'], value),
prop=range_prop,
read_permission=read_permission,
write_permission=write_permission)
write_permission=write_permission,
portal=portal)
# Create translation accesor, if translatable is set
if prop.get('translatable', 0):
......@@ -1325,8 +1340,15 @@ def setDefaultProperties(property_holder, object=None, portal=None):
createTranslationAccessors(
property_holder,
'translated_%s' % (prop['id']),
prop,
read_permission=read_permission,
write_permission=write_permission)
createTranslationLanguageAccessors(
property_holder,
prop,
read_permission=read_permission,
write_permission=write_permission,
portal=portal)
# make accessor to translation_domain
# first create default one as a normal property
txn_prop = {}
......@@ -1340,7 +1362,8 @@ def setDefaultProperties(property_holder, object=None, portal=None):
'%s_%s' %(prop['id'], txn_prop['id']),
prop=txn_prop,
read_permission=read_permission,
write_permission=write_permission)
write_permission=write_permission,
portal=portal)
# then overload accesors getPropertyTranslationDomain
if prop.has_key('translation_domain'):
default = prop['translation_domain']
......@@ -1349,6 +1372,7 @@ def setDefaultProperties(property_holder, object=None, portal=None):
createTranslationAccessors(
property_holder,
'%s_translation_domain' % (prop['id']),
prop,
read_permission=read_permission,
write_permission=write_permission,
default=default)
......@@ -1357,7 +1381,8 @@ def setDefaultProperties(property_holder, object=None, portal=None):
prop['id'],
prop=prop,
read_permission=read_permission,
write_permission=write_permission)
write_permission=write_permission,
portal=portal)
else:
raise TypeError, '"%s" is invalid type for propertysheet' % \
prop['type']
......@@ -1380,7 +1405,8 @@ def setDefaultProperties(property_holder, object=None, portal=None):
prop['id'],
prop=prop,
read_permission=Permissions.AccessContentsInformation,
write_permission=Permissions.ModifyPortalContent)
write_permission=Permissions.ModifyPortalContent,
portal=portal)
# Get read and write permission
if portal is not None:
......@@ -1508,7 +1534,8 @@ from Accessor import Base, List, Acquired, Content,\
def createDefaultAccessors(property_holder, id, prop = None,
read_permission=Permissions.AccessContentsInformation,
write_permission=Permissions.ModifyPortalContent):
write_permission=Permissions.ModifyPortalContent,
portal=None):
"""
This function creates accessor and setter for a class
and a property
......@@ -1519,6 +1546,12 @@ def createDefaultAccessors(property_holder, id, prop = None,
prop -- the property definition of the property
"""
######################################################
# Create Translation Acquired Accessors.
if prop.get('translation_acquired_property_id'):
createTranslationAcquiredPropertyAccessors(property_holder, prop,
portal=portal)
######################################################
# Create Getters
if prop.has_key('acquisition_base_category'):
......@@ -2565,29 +2598,198 @@ def createRelatedValueAccessors(property_holder, id, read_permission=Permissions
if accessor_name[0] != '_':
BaseClass.security.declareProtected(read_permission, accessor_name)
def createTranslationAccessors(property_holder, id,
def createTranslationAcquiredPropertyAccessors(
property_holder,
property,
read_permission=Permissions.AccessContentsInformation,
write_permission=Permissions.ModifyPortalContent,
portal=None):
"""Generate translation acquired property accessor to Base class"""
property = property.copy()
translation_acquired_property_id_list = []
accessor_dict_list = []
# Language Dependent Getter/Setter
for language in portal.Localizer.get_languages():
language_key = language.replace('-', '_')
for acquired_property_id in property['acquired_property_id']:
key = '%s_translated_%s' % (language_key, acquired_property_id)
capitalised_composed_id = UpperCase("%s_%s" % (property['id'], key))
accessor_args = (
property['type'],
property['portal_type'],
key,
property['acquisition_base_category'],
property['acquisition_portal_type'],
property['acquisition_accessor_id'],
property.get('acquisition_copy_value',0),
property.get('acquisition_mask_value',0),
property.get('acquisition_sync_value',0),
property.get('storage_id'),
property.get('alt_accessor_id'),
property.get('acquisition_object_id'),
(property['type'] in list_types or property.get('multivalued', 0)),
(property['type'] == 'tales'),
)
accessor_dict_list.append({'name':'get' + capitalised_composed_id,
'key': key,
'class':Translation.AcquiredPropertyGetter,
'argument':accessor_args,
'permission':read_permission})
accessor_dict_list.append({'name':'_baseGet' + capitalised_composed_id,
'key': key,
'class':Translation.AcquiredPropertyGetter,
'argument':accessor_args,
'permission':read_permission})
accessor_dict_list.append({'name': 'getDefault' + capitalised_composed_id,
'key': key,
'class': Translation.AcquiredPropertyGetter,
'argument': accessor_args,
'permission': read_permission})
accessor_dict_list.append({'name': 'set' + capitalised_composed_id,
'key': '_set' + capitalised_composed_id,
'class': Alias.Reindex,
'argument': (),
'permission': write_permission})
accessor_dict_list.append({'name': '_set' + capitalised_composed_id,
'key': key,
'class': AcquiredProperty.DefaultSetter,
'argument': accessor_args,
'permission': write_permission})
accessor_dict_list.append({'name': 'setDefault' + capitalised_composed_id,
'key': '_set' + capitalised_composed_id,
'class': Alias.Reindex,
'argument': (),
'permission': write_permission})
# Language Independent Getter
for acquired_property_id in property['acquired_property_id']:
if acquired_property_id in property.get('translation_acquired_property_id',()):
key = 'translated_%s' % acquired_property_id
capitalised_composed_id = UpperCase('%s_%s' % (property['id'], key))
accessor_args = (
property['type'],
property['portal_type'],
key,
property['acquisition_base_category'],
property['acquisition_portal_type'],
property['acquisition_accessor_id'],
property.get('acquisition_copy_value',0),
property.get('acquisition_mask_value',0),
property.get('acquisition_sync_value',0),
property.get('storage_id'),
property.get('alt_accessor_id'),
property.get('acquisition_object_id'),
(property['type'] in list_types or property.get('multivalued', 0)),
(property['type'] == 'tales'),
)
accessor_dict_list.append({'name': 'get' + capitalised_composed_id,
'key': key,
'class': Translation.AcquiredPropertyGetter,
'argument': accessor_args,
'permission': read_permission})
accessor_dict_list.append({'name': '_baseGet' + capitalised_composed_id,
'key': key,
'class': Translation.AcquiredPropertyGetter,
'argument': accessor_args,
'permission': read_permission})
accessor_dict_list.append({'name': 'getDefault' + capitalised_composed_id,
'key': key,
'class': Translation.AcquiredPropertyGetter,
'argument': accessor_args,
'permission': read_permission})
for accessor_dict in accessor_dict_list:
accessor_name = accessor_dict['name']
if getattr(property_holder, accessor_name, None) is None:
property_holder.registerAccessor(accessor_name, # id
accessor_dict['key'],
accessor_dict['class'],
accessor_dict['argument'])
property_holder.declareProtected(accessor_dict['permission'],
accessor_name)
def createTranslationAccessors(property_holder, id, property,
read_permission=Permissions.AccessContentsInformation,
write_permission=Permissions.ModifyPortalContent, default=''):
"""
Generate the translation accessor for a class and a property
"""
capitalised_id = UpperCase(id)
if 'translated' in id:
accessor_name = 'get' + UpperCase(id)
accessor_name = 'get' + capitalised_id
private_accessor_name = '_baseGet' + capitalised_id
if not hasattr(property_holder, accessor_name):
property_holder.registerAccessor(accessor_name, id, Translation.TranslatedPropertyGetter, ())
property_holder.registerAccessor(accessor_name,
id,
Translation.TranslatedPropertyGetter,
(property['id'], property['type'], None, default))
property_holder.declareProtected(read_permission, accessor_name)
accessor_name = '_baseGet' + UpperCase(id)
if not hasattr(property_holder, accessor_name):
property_holder.registerAccessor(accessor_name, id, Translation.TranslatedPropertyGetter, ())
if not hasattr(property_holder, private_accessor_name):
property_holder.registerAccessor(private_accessor_name,
id,
Translation.TranslatedPropertyGetter,
(property['id'], property['type'], None, default))
if 'translation_domain' in id:
# Getter
accessor_name = 'get' + UpperCase(id)
property_holder.registerAccessor(accessor_name, id,
Translation.PropertyTranslationDomainGetter, ('string', default,))
accessor_name = 'get' + capitalised_id
property_holder.registerAccessor(accessor_name,
id,
Translation.PropertyTranslationDomainGetter,
('string', default,))
property_holder.declareProtected(read_permission, accessor_name)
def createTranslationLanguageAccessors(property_holder, property,
read_permission=Permissions.AccessContentsInformation,
write_permission=Permissions.ModifyPortalContent, default='',
portal=None):
"""
Generate translation language accessors
"""
accessor_dict_list = []
for language in portal.Localizer.get_languages():
language_key = language.replace('-', '_')
composed_id = '%s_translated_%s' % (language_key, property['id'])
capitalised_compose_id = UpperCase(composed_id)
getter_accessor_args = (property['id'], property['type'], language, default)
accessor_dict_list.append({'name': 'get' + capitalised_compose_id,
'class': Translation.TranslatedPropertyGetter,
'argument': getter_accessor_args,
'permission': read_permission})
accessor_dict_list.append({'name': '_baseGet' + capitalised_compose_id,
'class': Translation.TranslatedPropertyGetter,
'argument': getter_accessor_args,
'permission': read_permission})
setter_accessor_args = (property['id'], property['type'], language)
accessor_dict_list.append({'name':'set' + capitalised_compose_id,
'key': '_set' + capitalised_compose_id,
'class': Alias.Reindex,
'argument': (),
'permission': write_permission})
setter_accessor_args = (property['id'], property['type'], language)
accessor_dict_list.append({'name': '_set' + capitalised_compose_id,
'class': Translation.TranslationPropertySetter,
'argument': setter_accessor_args,
'permission': write_permission})
for accessor_dict in accessor_dict_list:
accessor_name = accessor_dict['name']
if getattr(property_holder, accessor_name, None) is None:
property_holder.registerAccessor(accessor_name,
accessor_dict.get('key', None),
accessor_dict['class'],
accessor_dict['argument'])
property_holder.declareProtected(accessor_dict['permission'],
accessor_name)
#####################################################
# More Useful methods which require Base
#####################################################
......
##############################################################################
#
# Copyright (c) 2009 Nexedi KK, Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from zope.interface import Interface
class IPropertyTranslatable(Interface):
"""
"""
def getPropertyTranslation(property_id, language):
"""Retrieve translation text."""
def setPropertyTranslation(property_id, language, original_text, translation):
"""Store translation text."""
def deletePropertyTranslation(property_id, language):
"""Delete translation text."""
def getPropertyTranslationOriginalText(property_id, language):
"""Retrieve original text which is used for translation."""
def isPropertyTranslated(property_id, language):
"""Return True if property is translated, else return False"""
##############################################################################
#
# Copyright (c) 2009 Nexedi KK, Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import zope.interface
from Products.ERP5Type.interfaces.property_translatable import IPropertyTranslatable
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Globals import InitializeClass
INTERNAL_TRANSLATION_DICT_NAME = '__translation_dict'
class PropertyTranslatableBuiltInDictMixIn:
"""An implementation of IPropertyTranslatable with built-in dict."""
zope.interface.implements(IPropertyTranslatable)
security = ClassSecurityInfo()
def _getTranslationDict(self):
try:
return getattr(self, INTERNAL_TRANSLATION_DICT_NAME)
except AttributeError:
dict_ = {}
setattr(self, INTERNAL_TRANSLATION_DICT_NAME, dict_)
self._p_changed = True
return dict_
security.declareProtected(Permissions.AccessContentsInformation,
'getPropertyTranslation')
def getPropertyTranslation(self, property_id, language):
return self._getTranslationDict()[(property_id, language)][1]
security.declareProtected(Permissions.ModifyPortalContent,
'setPropertyTranslation')
def setPropertyTranslation(self, property_id, language, original_text, translation):
self._getTranslationDict()[(property_id, language)] = (original_text, translation)
self._p_changed = True
security.declareProtected(Permissions.ModifyPortalContent,
'deletePropertyTranslation')
def deletePropertyTranslation(self, property_id, language):
try:
del self._getTranslationDict()[(property_id, language)]
except KeyError:
pass
security.declareProtected(Permissions.AccessContentsInformation,
'getPropertyTranslationOriginalText')
def getPropertyTranslationOriginalText(self, property_id, language):
return self._getTranslationDict()[(property_id, language)][0]
security.declareProtected(Permissions.AccessContentsInformation,
'isPropertyTranslated')
def isPropertyTranslated(self, property_id, language):
try:
self._getTranslationDict()[(property_id, language)]
return True
except KeyError:
return False
InitializeClass(PropertyTranslatableBuiltInDictMixIn)
......@@ -126,3 +126,128 @@ def cleanup_and_export(self, x, REQUEST=None, RESPONSE=None):
return original_manage_export(self, x, REQUEST=REQUEST, RESPONSE=RESPONSE)
MessageCatalog.manage_export = cleanup_and_export
# Add a feature which allows users to be able to add a new language.
#
# Patch to LanguageManager.py
#
def get_languages_mapping(self):
"""
Returns a list of dictionary, one for each objects language. The
dictionary contains the language code, its name and a boolean
value that tells wether the language is the default one or not.
"""
return [ {'code': x,
'name': self.get_language_name(x),
'default': x == self._default_language}
for x in self._languages ]
def get_language_name(self, id=None):
"""
Returns the name of the given language code.
XXX Kept here for backwards compatibility only
"""
if id is None:
id = self.get_default_language()
language_name = LanguageManager.i18n.get_language_name(id)
if language_name=='???':
return self.get_user_defined_language_name(id) or language_name
else:
return language_name
# New method
def get_user_defined_language_name(self, id=None):
"""
Returns the name of the given user defined language code.
"""
for language_dict in self.get_user_defined_languages():
if language_dict['code']==id:
return language_dict['name']
def get_all_languages(self):
"""
Returns all ISO languages, used by 'manage_languages'.
"""
return LanguageManager.i18n.get_languages() + self.get_user_defined_languages()
# New method
def get_user_defined_languages(self):
user_define_language_dict_list = []
localizer = getattr(self, 'Localizer', None)
if localizer is not None:
for value in getattr(self, 'user_defined_languages', ()):
splitted_value = value.split(' ', 1)
if len(splitted_value)==2:
user_define_language_dict_list.append(
{'name':splitted_value[0].strip(),
'code':splitted_value[1].strip(),})
return user_define_language_dict_list
# New method
def _add_user_defined_language(self, language_name, language_code):
self.user_defined_languages = (
getattr(self, 'user_defined_languages', ())+
('%s %s' % (language_name, language_code),)
)
self._p_changed = True
# New method
def _del_user_defined_language(self, language_code):
user_defined_languages = []
for language_dict in self.get_user_defined_languages():
if language_dict['code']!=language_code:
user_defined_languages.append('%s %s' %
(language_dict['name'],
language_dict['code']))
self.user_defined_languages = tuple(user_defined_languages)
self._p_changed = True
from Products.Localizer import LanguageManager
LanguageManager.LanguageManager.get_languages_mapping = get_languages_mapping
LanguageManager.LanguageManager.get_language_name = get_language_name
LanguageManager.LanguageManager.get_all_languages = get_all_languages
LanguageManager.LanguageManager.get_user_defined_language_name = get_user_defined_language_name
LanguageManager.LanguageManager.get_user_defined_languages = get_user_defined_languages
LanguageManager.LanguageManager._add_user_defined_language = _add_user_defined_language
LanguageManager.LanguageManager._del_user_defined_language = _del_user_defined_language
LanguageManager.InitializeClass(LanguageManager.LanguageManager)
#
# Patch to Localizer.py
#
_properties = ({'id': 'title', 'type': 'string'},
{'id': 'accept_methods', 'type': 'tokens'},
{'id': 'user_defined_languages', 'type': 'lines'},)
user_defined_languages = ()
def get_languages_map(self):
"""
Return a list of dictionaries, each dictionary has the language
id, its title and a boolean value to indicate wether it's the
user preferred language, for example:
[{'id': 'en', 'title': 'English', 'selected': 1}]
Used in changeLanguageForm.
"""
# For now only LPM instances are considered to be containers of
# multilingual data.
try:
ob = self.getLocalPropertyManager()
except AttributeError:
ob = self
ob_language = ob.get_selected_language()
ob_languages = ob.get_available_languages()
langs = []
for x in ob_languages:
langs.append({'id': x, 'title': self.get_language_name(x),
'selected': x == ob_language})
return langs
from Products.Localizer import Localizer
Localizer.Localizer._properties = _properties
Localizer.Localizer.user_defined_languages = user_defined_languages
Localizer.Localizer.get_languages_map = get_languages_map
Localizer.InitializeClass(Localizer.Localizer)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment