New translation system, that generates screens for updating translations through the web, within the configuration.
This commit is contained in:
parent
f3604624de
commit
ead9f7c2de
22 changed files with 525 additions and 278 deletions
gen/plone25/wrappers
|
@ -105,4 +105,8 @@ class ToolWrapper(AbstractWrapper):
|
|||
res = '%sFor%s' % (attributeType, fullClassName)
|
||||
if attrName: res += '_%s' % attrName
|
||||
return res
|
||||
|
||||
def getAvailableLanguages(self):
|
||||
'''Returns the list of available languages for this application.'''
|
||||
return [(t.id, t.title) for t in self.translations]
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
76
gen/plone25/wrappers/TranslationWrapper.py
Normal file
76
gen/plone25/wrappers/TranslationWrapper.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import os.path
|
||||
from appy.gen.plone25.wrappers import AbstractWrapper
|
||||
from appy.gen.po import PoFile, PoMessage
|
||||
from appy.shared.utils import getOsTempFolder
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
class TranslationWrapper(AbstractWrapper):
|
||||
def computeLabel(self, field):
|
||||
'''The label for a text to translate displays the text of the
|
||||
corresponding message in the source translation.'''
|
||||
tool = self.tool
|
||||
sourceLanguage = self.o.getProductConfig().sourceLanguage
|
||||
sourceTranslation = getattr(tool.o, sourceLanguage).appy()
|
||||
# p_field is the Computed field. We need to get the name of the
|
||||
# corresponding field holding the translation message.
|
||||
fieldName = field.name[:-6]
|
||||
# If we are showing the source translation, we do not repeat the message
|
||||
# in the label.
|
||||
if self.id == sourceLanguage:
|
||||
sourceMsg = ''
|
||||
else:
|
||||
sourceMsg = getattr(sourceTranslation,fieldName)
|
||||
# When editing the value, we don't want HTML code to be interpreted.
|
||||
# This way, the translator sees the HTML tags and can reproduce them in
|
||||
# the translation.
|
||||
if self.request['URL'].endswith('/skyn/edit'):
|
||||
sourceMsg = sourceMsg.replace('<','<').replace('>','>')
|
||||
sourceMsg = sourceMsg.replace('\n', '<br/>')
|
||||
return '<div class="translationLabel"><acronym title="%s">' \
|
||||
'<img src="help.png"/></acronym>%s</div>' % \
|
||||
(fieldName, sourceMsg)
|
||||
|
||||
def showField(self, field):
|
||||
'''We show a field (or its label) only if the corresponding source
|
||||
message is not empty.'''
|
||||
tool = self.tool
|
||||
if field.type == 'Computed': name = field.name[:-6]
|
||||
else: name = field.name
|
||||
# Get the source message
|
||||
sourceLanguage = self.o.getProductConfig().sourceLanguage
|
||||
sourceTranslation = getattr(tool.o, sourceLanguage).appy()
|
||||
sourceMsg = getattr(sourceTranslation, name)
|
||||
if field.isEmptyValue(sourceMsg): return False
|
||||
return True
|
||||
|
||||
poReplacements = ( ('\r\n', '<br/>'), ('\n', '<br/>'), ('"', '\\"') )
|
||||
def getPoFile(self):
|
||||
'''Computes and returns the PO file corresponding to this
|
||||
translation.'''
|
||||
tool = self.tool
|
||||
fileName = os.path.join(getOsTempFolder(),
|
||||
'%s-%s.po' % (tool.o.getAppName(), self.id))
|
||||
poFile = PoFile(fileName)
|
||||
for field in self.fields:
|
||||
if (field.name == 'title') or (field.type != 'String'): continue
|
||||
# Adds the PO message corresponding to this field
|
||||
msg = field.getValue(self.o) or ''
|
||||
for old, new in self.poReplacements:
|
||||
msg = msg.replace(old, new)
|
||||
poFile.addMessage(PoMessage(field.name, msg, ''))
|
||||
poFile.generate()
|
||||
return True, file(fileName)
|
||||
|
||||
def validate(self, new, errors):
|
||||
# Call a custom "validate" if any.
|
||||
self._callCustom('validate', new, errors)
|
||||
|
||||
def onEdit(self, created):
|
||||
# Call a custom "onEdit" if any.
|
||||
self._callCustom('onEdit', created)
|
||||
|
||||
def onDelete(self):
|
||||
# Call a custom "onDelete" if any.
|
||||
self._callCustom('onDelete')
|
||||
# ------------------------------------------------------------------------------
|
|
@ -4,17 +4,6 @@ from appy.gen.plone25.wrappers import AbstractWrapper
|
|||
# ------------------------------------------------------------------------------
|
||||
class UserWrapper(AbstractWrapper):
|
||||
|
||||
def _callCustom(self, methodName, *args, **kwargs):
|
||||
'''This wrapper implements some methods like "validate" and "onEdit".
|
||||
If the user has defined its own wrapper, its methods will not be
|
||||
called. So this method allows, from the methods here, to call the
|
||||
user versions.'''
|
||||
if len(self.__class__.__bases__) > 1:
|
||||
# There is a custom user class
|
||||
customUser = self.__class__.__bases__[-1]
|
||||
if customUser.__dict__.has_key(methodName):
|
||||
customUser.__dict__[methodName](self, *args, **kwargs)
|
||||
|
||||
def showLogin(self):
|
||||
'''When must we show the login field?'''
|
||||
if self.o.isTemporary(): return 'edit'
|
||||
|
|
|
@ -33,6 +33,17 @@ class AbstractWrapper:
|
|||
if other: return cmp(self.o, other.o)
|
||||
else: return 1
|
||||
|
||||
def _callCustom(self, methodName, *args, **kwargs):
|
||||
'''This wrapper implements some methods like "validate" and "onEdit".
|
||||
If the user has defined its own wrapper, its methods will not be
|
||||
called. So this method allows, from the methods here, to call the
|
||||
user versions.'''
|
||||
if len(self.__class__.__bases__) > 1:
|
||||
# There is a custom user class
|
||||
customUser = self.__class__.__bases__[-1]
|
||||
if customUser.__dict__.has_key(methodName):
|
||||
customUser.__dict__[methodName](self, *args, **kwargs)
|
||||
|
||||
def get_tool(self): return self.o.getTool().appy()
|
||||
tool = property(get_tool)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue