appy.gen: solved a tricky encoding problem.

This commit is contained in:
Gaetan Delannay 2011-12-08 16:01:57 +01:00
parent d5f26dd1df
commit c1174fac79
6 changed files with 60 additions and 67 deletions

View file

@ -1 +1 @@
0.7.1
0.8.0

View file

@ -2556,8 +2556,7 @@ class Transition:
notifier.sendMail(obj.appy(), self, transitionName, wf)
# Return a message to the user if needed
if not doSay or (transitionName == '_init_'): return
if not msg:
msg = obj.translate(u'Changes saved.')
if not msg: msg = 'Changes saved.' # XXX Translate
obj.say(msg)
class Permission:

View file

@ -370,15 +370,21 @@ class ToolMixin(BaseMixin):
maxWidth = appyType['width']
if isinstance(value, str): value = value.decode('utf-8')
if len(value) > maxWidth:
return value[:maxWidth] + '...'
return value
return value[:maxWidth].encode('utf-8') + '...'
return value.encode('utf-8')
def truncateText(self, text, width=15):
'''Truncates p_text to max p_width chars. If the text is longer than
p_width, the truncated part is put in a "acronym" html tag.'''
if isinstance(text, str): text = text.decode('utf-8')
if len(text) <= width: return text
return '<acronym title="%s">%s</acronym>' % (text, text[:width] + '...')
# p_text has to be unicode-encoded for being truncated (else, one char
# may be spread on 2 chars). But this method must return an encoded
# string, else, ZPT crashes. The same remark holds for m_truncateValue
# above.
uText = text # uText will store the unicode version
if isinstance(text, str): uText = text.decode('utf-8')
if len(uText) <= width: return text
return '<acronym title="%s">%s</acronym>' % \
(text, uText[:width].encode('utf-8') + '...')
def getPublishedObject(self):
'''Gets the currently published object, if its meta_class is among
@ -820,9 +826,8 @@ class ToolMixin(BaseMixin):
urlBack = rq['HTTP_REFERER']
if jsEnabled and not cookiesEnabled:
msg = self.translate(u'You must enable cookies before you can ' \
'log in.')
return self.goto(urlBack, msg.encode('utf-8'))
msg = 'You must enable cookies before you can log in.' # XXX transl.
return self.goto(urlBack, msg)
# Perform the Zope-level authentication
login = rq.get('__ac_name', '')
password = rq.get('__ac_password', '')
@ -832,12 +837,11 @@ class ToolMixin(BaseMixin):
user = self.acl_users.validate(rq)
if self.userIsAnon():
rq.RESPONSE.expireCookie('__ac', path='/')
msg = self.translate(u'Login failed')
msg = 'Login failed' # XXX to translate
logMsg = 'Authentication failed (tried with login "%s")' % login
else:
msg = self.translate(u'Welcome! You are now logged in.')
msg = 'Welcome! You are now logged in.' # XXX to translate
logMsg = 'User "%s" has been logged in.' % login
msg = msg.encode('utf-8')
self.log(logMsg)
# Bring Managers to the config, leave others on the main page.
user = self.getUser()

View file

@ -184,7 +184,7 @@ class BaseMixin:
fields in the database.'''
rq = self.REQUEST
tool = self.getTool()
errorMessage = self.translate('Please correct the indicated errors.')
errorMessage = 'Please correct the indicated errors.' # XXX Translate
isNew = rq.get('is_new') == 'True'
# If this object is created from an initiator, get info about him.
initiator = None
@ -205,7 +205,7 @@ class BaseMixin:
urlBack = tool.getSiteUrl()
else:
urlBack = self.getUrl()
self.say(self.translate('Changes canceled.'))
self.say('Changes canceled.') # XXX Translate
return self.goto(urlBack)
# Object for storing validation errors
@ -241,7 +241,7 @@ class BaseMixin:
obj, msg = self.createOrUpdate(isNew, values, initiator, initiatorField)
# Redirect the user to the appropriate page
if not msg: msg = obj.translate('Changes saved.')
if not msg: msg = 'Changes saved.' # XXX Translate
# If the object has already been deleted (ie, it is a kind of transient
# object like a one-shot form and has already been deleted in method
# onEdit), redirect to the main site page.
@ -1058,7 +1058,7 @@ class BaseMixin:
instead of returning a list of string values, the result is a list
of tuples (s_value, s_translation). If p_withBlankValue is True, a
blank value is prepended to the list. If no p_className is defined,
the field is supposed to belong to self's class'''
the field is supposed to belong to self's class.'''
appyType = self.getAppyType(name, className=className)
if className:
# We need an instance of className, but self can be an instance of
@ -1333,51 +1333,40 @@ class BaseMixin:
p_mapping.'''
cfg = self.getProductConfig()
if not domain: domain = cfg.PROJECTNAME
if domain != cfg.PROJECTNAME:
# We need to translate something that is in a standard Zope catalog
try:
res = self.Control_Panel.TranslationService.utranslate(
domain, label, mapping, self, default=default,
target_language=language)
except AttributeError:
# When run in test mode, Zope does not create the
# TranslationService
res = label
else:
# Get the label name, and the field-specific mapping if any.
if field:
# p_field is the dict version of a appy type or group
if field['type'] != 'group':
fieldMapping = field['mapping'][label]
if fieldMapping:
if callable(fieldMapping):
appyField = self.getAppyType(field['name'])
fieldMapping=appyField.callMethod(self,fieldMapping)
mapping.update(fieldMapping)
label = field['%sId' % label]
# We will get the translation from a Translation object.
# In what language must we get the translation?
if not language: language = self.getUserLanguage()
tool = self.getTool()
try:
translation = getattr(tool, language).appy()
except AttributeError:
# We have no translation for this language. Fallback to 'en'.
translation = getattr(tool, 'en').appy()
# Get the label name, and the field-specific mapping if any.
if field:
# p_field is the dict version of a appy type or group
if field['type'] != 'group':
fieldMapping = field['mapping'][label]
if fieldMapping:
if callable(fieldMapping):
appyField = self.getAppyType(field['name'])
fieldMapping=appyField.callMethod(self,fieldMapping)
mapping.update(fieldMapping)
label = field['%sId' % label]
# We will get the translation from a Translation object.
# In what language must we get the translation?
if not language: language = self.getUserLanguage()
tool = self.getTool()
try:
translation = getattr(tool, language).appy()
except AttributeError:
# We have no translation for this language. Fallback to 'en'.
translation = getattr(tool, 'en').appy()
res = getattr(translation, label, '')
if not res:
# Fallback to 'en'.
translation = getattr(tool, 'en').appy()
res = getattr(translation, label, '')
if not res:
# Fallback to 'en'.
translation = getattr(tool, 'en').appy()
res = getattr(translation, label, '')
# If still no result, put the label instead of a translated message
if not res: res = label
else:
# Perform replacements, according to p_format.
res = self.formatText(res, format)
# Perform variable replacements
for name, repl in mapping.iteritems():
if not isinstance(repl, basestring): repl = str(repl)
res = res.replace('${%s}' % name, repl)
# If still no result, put the label instead of a translated message
if not res: res = label
else:
# Perform replacements, according to p_format.
res = self.formatText(res, format)
# Perform variable replacements
for name, repl in mapping.iteritems():
if not isinstance(repl, basestring): repl = str(repl)
res = res.replace('${%s}' % name, repl)
return res
def getPageLayout(self, layoutType):

View file

@ -8,7 +8,7 @@
_ python: tool.translate;
req python: request;
resp req/RESPONSE;
x python: resp.setHeader('Content-Type', 'text/html;;charset=utf-8');
x python: resp.setHeader('Content-Type', 'text/html;;charset=UTF-8');
x python: resp.setHeader('Expires', 'Thu, 11 Dec 1975 12:05:00 GMT+2');
x python: resp.setHeader('Content-Language', req.get('language', 'en'))">

View file

@ -13,17 +13,17 @@ class UserWrapper(AbstractWrapper):
'''Is this p_login valid?'''
# The login can't be the id of the whole site or "admin"
if login == 'admin':
return self.translate('This username is reserved.')
return 'This username is reserved.' # XXX Translate
# Check that no user or group already uses this login.
if self.count('User', login=login) or self.count('Group', login=login):
return self.translate('This login is already in use.')
return 'This login is already in use.' # XXX Translate
return True
def validatePassword(self, password):
'''Is this p_password valid?'''
# Password must be at least 5 chars length
if len(password) < 5:
return self.translate('Passwords must contain at least 5 letters.')
return 'Passwords must contain at least 5 letters.' # XXX Translate
return True
def showPassword(self):
@ -43,7 +43,8 @@ class UserWrapper(AbstractWrapper):
page = self.request.get('page', 'main')
if page == 'main':
if hasattr(new, 'password1') and (new.password1 != new.password2):
msg = self.translate('Passwords do not match.')
# XXX Translate
msg = 'Passwords do not match.'
errors.password1 = msg
errors.password2 = msg
return self._callCustom('validate', new, errors)