admin: add a custom translations setting page

It allows overriding default translations from the admin.
This commit is contained in:
Benjamin Dauvergne 2014-01-09 17:44:38 +01:00
parent 3eb3755ecd
commit 040afeecda
2 changed files with 182 additions and 0 deletions

155
admin/translations.ptl Normal file
View File

@ -0,0 +1,155 @@
# w.c.s. - web application for online forms
# Copyright (C) 2005-2010 Entr'ouvert
#
# 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., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
import os
from cStringIO import StringIO
from quixote import redirect, get_publisher, get_request, get_response
from quixote.html import htmltext
from quixote.directory import Directory
from qommon import misc, get_cfg, ezt
from qommon.misc import is_user_admin
from qommon.admin.menu import html_top
from cfg import cfg_submit
from ..utils import get_for_current_language
from ..translations import get_translation_keys
class TranslationsDirectory(Directory):
_q_exports = ['']
def html_top(self, title):
html_top('settings', title)
def _q_index [html] (self):
self.html_top( title = _('Custom Translations'))
'<h2>%s</h2>' % _('Custom Translations')
custom_translations = get_cfg('custom_translations', {})
publisher = get_publisher()
'<ul>'
for language in publisher.supported_languages:
'<li><a href="%s">%s (%s translations)</a></li>' % (language,
language, len(custom_translations.get(language, [])))
'</ul>'
'<p>'
'<a href="..">%s</a>' % _('Back')
'</p>'
def translations_submit(self, language):
custom_translations = get_cfg('custom_translations', {})
custom_translation = custom_translations.get(language, {})
request = get_request()
publisher = get_publisher()
post = request.form
for key in post:
if not key.endswith('-key'):
continue
ignore, number, ignore = key.split('-')
key = post.get(key)
value = post.get('translation-%s-value' % number)
if not value:
custom_translation.pop(key, None)
else:
custom_translation[key] = value
custom_translations[language] = custom_translation
publisher.cfg['custom_translations'] = custom_translations
publisher.write_cfg()
return redirect('')
def translations [html] (self, language):
custom_translations = get_cfg('custom_translations', {})
custom_translation = custom_translations.get(language, {})
request = get_request()
publisher = get_publisher()
if request.get_method() == 'POST':
return self.translations_submit(language)
get_response().breadcrumb.append((language, language))
self.html_top(title=language)
keys = sorted(custom_translation.keys())
keys += sorted(set(get_translation_keys())-set(keys))
'''<style>
.message, .custom-translation, .default-translation {
width: 30%;
}
.submit {
position: fixed;
right: 10%;
width: 10%;
height: 10%;
}
thead {
background: black;
color: white;
text-weight: bold;
}
thead td {
padding: 10px;
}
td {
padding: 5px;
padding-right: 10px;
vertical-align: top;
}
tbody tr:nth-child(even) td{
background: grey;
}
table {
border-spacing: 0px;
}
pre {
white-space: normal;
}
</style>'''
'<form method="post"><table>'
i = 0
'<input class="submit" type="submit" name="submit" value="%s">' % _('Submit')
'<thead><tr><td>%s</td>' % _('Message')
'<td>%s</td>' % _('Custom translation')
'<td>%s</td></tr></thead>' % _('Default translation')
'<tbody>'
for key in keys:
if not key:
continue
static_translation = publisher.get_translation(language).gettext(key)
static_translation = publisher.utf82sitecharset(static_translation)
local_translation = custom_translation.get(key, '')
'<tr>'
'<td class="message"><pre>%s</pre><input type="hidden" name="translation-%s-key" value="%s"/></td>' % (key, i, key)
'<td class="custom-translation"><textarea rows="10" cols="50" name="translation-%s-value">%s</textarea></td>' % (i, local_translation)
'<td class="default-translation"><pre>%s</pre></td>' % static_translation
'</tr>'
i += 1
'</tbody>'
'</table>'
'</form>'
def _q_lookup(self, component):
publisher = get_publisher()
if not component in publisher.supported_languages:
return None
return self.translations(component)
def _q_traverse(self, path):
get_response().breadcrumb.append(('translations/', _('Custom Translations')))
return Directory._q_traverse(self, path)

27
translations.py Normal file
View File

@ -0,0 +1,27 @@
from quixote import get_publisher
from gettext import NullTranslations
class DictionnaryTranslations(NullTranslations):
def __init__(self, dictionnary):
self._dictionnary = dictionnary
NullTranslations.__init__(self)
def gettext(self, message):
if message in self._dictionnary:
return self._dictionnary[message]
return NullTranslations.gettext(self, message)
def get_translation_keys():
'''Return all currently translated messages'''
publisher = get_publisher()
keys = set()
for translation in publisher.translations.values():
while translation is not None:
if hasattr(translation, '_catalog'):
keys.update(translation._catalog.keys())
translation = getattr(translation, '_fallback', None)
# catalogs contain unicode
return map(lambda x: x.encode(publisher.site_charset), keys)