Fork Localizer and itools

Fork from master branch of Localizer and 0.50 branch of itools into ERP5

Remove almost everything from itools except bare essentials needed by a stripped Localizer for ERP5
parent 498500ed
*.pyc
*.swp
locale/*.mo
locale/*~
# -*- coding: UTF-8 -*-
# Copyright (C) 2000-2002 Juan David Ibáñez Palomar <jdavid@itaapy.com>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
"""
Localizer
Adds a new DTML tag:
<dtml-gettext [lang=<language>|lang_expr=<expression>] [verbatim] [catalog=<id>] [data=<expression>]>
...
</dtml-gettext>
"""
# Import from Zope
from DocumentTemplate.DT_Util import Eval, ParseError, parse_params, \
InstanceDict, namespace, render_blocks
# Auxiliar functions
def name_or_expr(mapping, name_attr, expr_attr, default):
name = mapping.get(name_attr, None)
expr = mapping.get(expr_attr, None)
if name is None:
if expr is None:
return default
return Eval(expr)
if expr is None:
return name
raise ParseError, ('%s and %s given' % (name_attr, expr_attr), 'calendar')
class GettextTag:
""" """
name = 'gettext'
blockContinuations = ()
def __init__(self, blocks):
tname, args, section = blocks[0]
self.section = section.blocks
args = parse_params(args, lang=None, lang_expr=None, verbatim=1,
catalog=None, data=None)
self.lang = name_or_expr(args, 'lang', 'lang_expr', None)
self.verbatim = args.get('', None) == 'verbatim' \
or args.get('verbatim', None)
self.catalog = args.get('catalog', None)
self.data = args.get('data', None)
if self.data is not None:
self.data = Eval(self.data)
def __call__(self, md):
# In which language, if any?
lang = self.lang
if lang is not None and type(lang) is not str:
lang = lang.eval(md)
# Get the message!!
ns = namespace(md)[0]
md._push(InstanceDict(ns, md))
message = render_blocks(self.section, md)
md._pop(1)
# Interpret the message as verbatim or not
if not self.verbatim:
message = ' '.join([ x.strip() for x in message.split() ])
# Search in a specific catalog
if self.catalog is None:
gettext = md.getitem('gettext', 0)
else:
gettext = md.getitem(self.catalog, 0).gettext
translation = gettext(message, lang)
# Variable substitution
if self.data is not None:
data = self.data.eval(md)
translation = translation % data
return translation
This diff is collapsed.
# -*- coding: UTF-8 -*-
# Copyright (C) 2000-2004 Juan David Ibáñez Palomar <jdavid@itaapy.com>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
# Import from the Standard Library
from urlparse import urlparse
# Import from itools
from itools.i18n import get_language_name, get_languages
# Import from Zope
from App.class_init import InitializeClass
from App.Management import Tabs
from AccessControl import ClassSecurityInfo
# Import from Localizer
from LocalFiles import LocalDTMLFile
from utils import lang_negotiator, _
class LanguageManager(Tabs):
""" """
security = ClassSecurityInfo()
# TODO For backwards compatibility with Python 2.1 the variable
# _languages is a tuple. Change it to a frozenset.
_languages = ()
_default_language = None
########################################################################
# API
########################################################################
def get_languages(self):
"""Returns all the object languages.
"""
return self._languages
def set_languages(self, languages):
"""Sets the object languages.
"""
self._languages = tuple(languages)
def add_language(self, language):
"""Adds a new language.
"""
if language not in self._languages:
self._languages = tuple(self._languages) + (language,)
def del_language(self, language):
"""Removes a language.
"""
if language in self._languages:
languages = [ x for x in self._languages if x != language ]
self._languages = tuple(languages)
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': get_language_name(x),
'default': x == self._default_language}
for x in self._languages ]
def get_available_languages(self, **kw):
"""Returns the langauges available. For example, a language could be
considered as available only if there is some data associated to it.
This method is used by the language negotiation code (see
'get_selected_language'), sometimes you will want to redefine it in
your classes.
"""
return self._languages
def get_default_language(self):
"""Returns the default language.
This method is used by the language negotiation code (see
'get_selected_language'), sometimes you will want to redefine it in
your classes.
For example, maybe you will want to define it to return always a
default language, even when internally it is None.
"""
return self._default_language
########################################################################
# Web API
########################################################################
# Security settings
security.declarePublic('get_languages')
security.declareProtected('Manage languages', 'set_languages')
security.declareProtected('Manage languages', 'add_language')
security.declareProtected('Manage languages', 'del_language')
security.declarePublic('get_languages_mapping')
security.declarePublic('get_language_name')
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()
return get_language_name(id)
security.declarePublic('get_available_languages')
security.declarePublic('get_default_language')
# XXX Kept here temporarily, further refactoring needed
security.declarePublic('get_selected_language')
def get_selected_language(self, **kw):
"""
Returns the selected language. Here the language negotiation takes
place.
Accepts keyword arguments which will be passed to
'get_available_languages'.
"""
available_languages = apply(self.get_available_languages, (), kw)
return lang_negotiator(available_languages) \
or self.get_default_language()
########################################################################
# ZMI
########################################################################
manage_options = (
{'action': 'manage_languages', 'label': u'Languages',
'help': ('Localizer', 'LM_languages.stx')},)
def filtered_manage_options(self, REQUEST=None):
options = Tabs.filtered_manage_options(self, REQUEST=REQUEST)
# Insert the upgrade form if needed
if self._needs_upgrade():
options.insert(0,
{'action': 'manage_upgradeForm',
'label': u'Upgrade',
'help': ('Localizer', 'LM_upgrade.stx')})
# Translate the labels
r = []
for option in options:
option = option.copy()
option['label'] = _(option['label'])
r.append(option)
# Ok
return r
security.declareProtected('View management screens', 'manage_languages')
manage_languages = LocalDTMLFile('ui/LM_languages', globals())
security.declarePublic('get_all_languages')
def get_all_languages(self):
"""
Returns all ISO languages, used by 'manage_languages'.
"""
return get_languages()
security.declareProtected('Manage languages', 'manage_addLanguage')
def manage_addLanguage(self, language, REQUEST=None, RESPONSE=None):
""" """
self.add_language(language)
if RESPONSE is not None:
RESPONSE.redirect("%s/manage_languages" % REQUEST['URL1'])
security.declareProtected('Manage languages', 'manage_delLanguages')
def manage_delLanguages(self, languages, REQUEST, RESPONSE):
""" """
for language in languages:
self.del_language(language)
RESPONSE.redirect("%s/manage_languages" % REQUEST['URL1'])
security.declareProtected('Manage languages', 'manage_changeDefaultLang')
def manage_changeDefaultLang(self, language, REQUEST=None, RESPONSE=None):
""" """
self._default_language = language
if REQUEST is not None:
RESPONSE.redirect("%s/manage_languages" % REQUEST['URL1'])
# Unicode support, custom ZMI
manage_page_header = LocalDTMLFile('ui/manage_page_header', globals())
########################################################################
# Upgrade
def _needs_upgrade(self):
return False
def _upgrade(self):
pass
security.declarePublic('need_upgrade')
def need_upgrade(self):
""" """
return self._needs_upgrade()
security.declareProtected(
'Manage Access Rules', 'manage_upgradeForm', 'manage_upgrade')
manage_upgradeForm = LocalDTMLFile('ui/LM_upgrade', globals())
def manage_upgrade(self, REQUEST, RESPONSE):
""" """
self._upgrade()
RESPONSE.redirect('manage_main')
InitializeClass(LanguageManager)
# -*- coding: UTF-8 -*-
# Copyright (C) 2000-2002 Juan David Ibáñez Palomar <jdavid@itaapy.com>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
# Import from Zope
from ExtensionClass import Base
class LocalAttribute(Base):
"""
Provides a way to override class variables, useful for example
for title (defined in SimpleItem).
"""
def __init__(self, id):
self.id = id
def __of__(self, parent):
return parent.getLocalAttribute(self.id)
class LocalAttributesBase:
def getLocalAttribute(self, name, lang=None):
""" """
raise NotImplemented
class LocalAttributes(LocalAttributesBase):
"""
Example of a 'LocalAttributesBase' derived class, this also a base class
for 'LocalFolder.LocalFolder' and 'Locale.Locale', it can be considered
the default implementation.
Returns attributes of the form <name>_<lang>. When <lang> has more than
one level, for example es-CO, the dashes are transformed to underscores,
as dashes aren't valid charecters for identifiers in Python. For example,
the call 'getLocalAttribute("long_date", "es-CO")' would return
'self.long_date_es_CO'.
"""
def getLocalAttribute(self, name, lang=None):
if lang is None:
lang = self.get_selected_language()
lang = lang.replace('-', '_')
name = '%s_%s' % (name, lang)
return getattr(self, name)
This diff is collapsed.
# -*- coding: UTF-8 -*-
# Copyright (C) 2000-2005 Juan David Ibáñez Palomar <jdavid@itaapy.com>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
"""
Localizer
This module provides several localized classes, that is, classes with the
locale attribute. Currently it only defines the classes LocalDTMLFile and
LocalPageTemplateFile, which should be used instead of DTMLFile and
PageTemplateFile.
"""
# Import from the Standard Library
import os
# Import Zope modules
from App.special_dtml import DTMLFile
# Import from Localizer
from utils import DomainAware
class LocalDTMLFile(DomainAware, DTMLFile):
""" """
def __init__(self, name, _prefix=None, **kw):
DTMLFile.__init__(self, name, _prefix, **kw)
DomainAware.__init__(self, _prefix)
def _exec(self, bound_data, args, kw):
# Add our gettext first
bound_data['gettext'] = self.gettext
return apply(LocalDTMLFile.inheritedAttribute('_exec'),
(self, bound_data, args, kw))
# Zope Page Templates (ZPT)
# XXX Deprecated, use the i18n namespace instead.
try:
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
except ImportError:
# If ZPT is not installed
class LocalPageTemplateFile:
pass
else:
class LocalPageTemplateFile(DomainAware, PageTemplateFile):
""" """
def __init__(self, name, _prefix=None, **kw):
PageTemplateFile.__init__(self, name, _prefix, **kw)
DomainAware.__init__(self, _prefix)
def _exec(self, bound_data, args, kw):
# Add our gettext first
bound_data['gettext'] = self.gettext
return apply(LocalPageTemplateFile.inheritedAttribute('_exec'),
(self, bound_data, args, kw))
# -*- coding: UTF-8 -*-
# Copyright (C) 2000-2004 Juan David Ibáñez Palomar <jdavid@itaapy.com>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
# Import from Zope
from App.Common import package_home
from OFS.Folder import Folder
# Import from Localizer
from LanguageManager import LanguageManager
from LocalFiles import LocalDTMLFile
from LocalAttributes import LocalAttribute, LocalAttributes
from utils import _
manage_addLocalFolderForm = LocalDTMLFile('ui/LocalFolder_add', globals())
def manage_addLocalFolder(self, id, title, languages, REQUEST=None):
""" """
id = id.strip()
self._setObject(id, LocalFolder(id, title, languages))
if REQUEST is not None:
return self.manage_main(self, REQUEST)
class LocalFolder(LanguageManager, LocalAttributes, Folder):
""" """
meta_type = 'LocalFolder'
_properties = ({'id': 'title', 'type': 'string'},)
def __init__(self, id, title, languages):
self.id = id
self.title = title
# Language Manager data
self._languages = tuple(languages)
self._default_language = languages[0]
# Local attributes
self._local_attributes = ()
manage_options = \
Folder.manage_options[:1] \
+ ({'action': 'manage_attributes', 'label': u'Attributes'},) \
+ LanguageManager.manage_options \
+ Folder.manage_options[1:]
# Manage attributes
manage_attributes = LocalDTMLFile('ui/LocalFolder_attributes', globals())
def get_local_attributes(self):
return self._local_attributes
def manage_delAttributes(self, attributes, REQUEST=None, RESPONSE=None):
""" """
local_attributes = list(self._local_attributes)
for attr in attributes:
local_attributes.remove(attr)
delattr(self, attr)
self._local_attributes = tuple(local_attributes)
if RESPONSE is not None:
RESPONSE.redirect("%s/manage_attributes" % REQUEST['URL1'])
def manage_addAttribute(self, id, REQUEST=None, RESPONSE=None):
""" """
id = id.strip()
setattr(self, id, LocalAttribute(id))
self._local_attributes = self._local_attributes + (id,)
if RESPONSE is not None:
RESPONSE.redirect("%s/manage_attributes" % REQUEST['URL1'])
This diff is collapsed.
# -*- coding: UTF-8 -*-
# Copyright (C) 2000-2002 Juan David Ibáñez Palomar <jdavid@itaapy.com>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
# Import from Localizer
from LocalAttributes import LocalAttributes, LocalAttribute
class Locale(LocalAttributes):
# Time, hours and minutes
time = LocalAttribute('time')
def time_en(self, datetime):
return datetime.strftime('%H:%M')
def time_es(self, datetime):
return datetime.strftime('%H.%M')
# -*- coding: UTF-8 -*-
# Copyright (C) 2000-2004 Juan David Ibáñez Palomar <jdavid@itaapy.com>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
# Import from the Standard Library
from urllib import unquote
# Import from itools
from itools.i18n import get_language_name
# Import from Zope
from AccessControl import ClassSecurityInfo
from Acquisition import aq_parent
from App.class_init import InitializeClass
from OFS.Folder import Folder
from zLOG import LOG, ERROR, INFO, PROBLEM
from zope.interface import implements
from ZPublisher.BeforeTraverse import registerBeforeTraverse, \
unregisterBeforeTraverse, queryBeforeTraverse, NameCaller
# Import Localizer modules
from interfaces import ILocalizer
from LocalFiles import LocalDTMLFile
from MessageCatalog import MessageCatalog
from utils import lang_negotiator
from LanguageManager import LanguageManager
# Constructors
manage_addLocalizerForm = LocalDTMLFile('ui/Localizer_add', globals())
def manage_addLocalizer(self, title, languages, REQUEST=None, RESPONSE=None):
"""
Add a new Localizer instance.
"""
self._setObject('Localizer', Localizer(title, languages))