Add language select box, LINGUAS file, and relevant documentation.
This commit is contained in:
parent
2127f7be28
commit
57b731daed
9 changed files with 71 additions and 22 deletions
|
@ -135,3 +135,11 @@ To generate the POT file (located in the po/ subdirectory), run the
|
|||
following from the top level directory:
|
||||
|
||||
pybabel extract -F pybabel.conf -o po/fas.pot .
|
||||
|
||||
Message merging should be done manually using msgmerge at this point.
|
||||
|
||||
python setup.py build
|
||||
|
||||
compiles the PO files and places them where TurboGears will look for
|
||||
them. To enable a language to be available to users, it must be added
|
||||
to po/LINGUAS.
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
[global]
|
||||
|
||||
theme = 'fas'
|
||||
# TODO: better namespacing (maybe a [fas] section)
|
||||
admingroup = 'accounts'
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ from fas.cla import CLA
|
|||
from fas.json_request import JsonRequest
|
||||
from fas.help import Help
|
||||
from fas.auth import *
|
||||
from fas.util import available_languages
|
||||
#from fas.openid_fas import OpenID
|
||||
|
||||
import os
|
||||
|
@ -21,11 +22,6 @@ import sys
|
|||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
|
||||
def add_custom_stdvars(vars):
|
||||
return vars.update({"gettext": _})
|
||||
|
||||
turbogears.view.variable_providers.append(add_custom_stdvars)
|
||||
|
||||
def get_locale(locale=None):
|
||||
if locale:
|
||||
return locale
|
||||
|
@ -36,6 +32,12 @@ def get_locale(locale=None):
|
|||
|
||||
config.update({'i18n.get_locale': get_locale})
|
||||
|
||||
def add_custom_stdvars(vars):
|
||||
return vars.update({'gettext': _, "lang": get_locale(), 'available_languages': available_languages()})
|
||||
|
||||
turbogears.view.variable_providers.append(add_custom_stdvars)
|
||||
|
||||
|
||||
# from fas import json
|
||||
# import logging
|
||||
# log = logging.getLogger("fas.controllers")
|
||||
|
@ -138,8 +140,11 @@ class Root(controllers.RootController):
|
|||
|
||||
@expose()
|
||||
def language(self, locale):
|
||||
locale_key = config.get("i18n.session_key", "locale")
|
||||
cherrypy.session[locale_key] = locale
|
||||
raise redirect(request.headers.get("Referer", "/"))
|
||||
|
||||
if locale not in available_languages():
|
||||
turbogears.flash(_('The language \'%s\' is not available.') % locale)
|
||||
redirect(request.headers.get("Referer", "/"))
|
||||
return dict()
|
||||
turbogears.i18n.set_session_locale(locale)
|
||||
redirect(request.headers.get("Referer", "/"))
|
||||
return dict()
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
xmlns:py="http://genshi.edgewall.org/"
|
||||
py:strip="">
|
||||
<?python
|
||||
from turbogears import config
|
||||
_ = lambda text: tg.gettext(text)
|
||||
?>
|
||||
<?python from turbogears import config ?>
|
||||
<head py:match="head" py:attrs="select('@*')">
|
||||
<link href="${tg.url('/static/theme/%s/css/style.css') % config.get('theme')}" rel="stylesheet" type="text/css" />
|
||||
<link rel="shortcut icon" href="${tg.url('/static/theme/%s/images/favicon.ico' % config.get('theme'))}" type="image/vnd.microsoft.icon" />
|
||||
|
@ -68,15 +68,16 @@
|
|||
<li py:if="not tg.identity.anonymous"><a href="${tg.url('/group/list/A*')}">${_('Apply For a new Group')}</a></li>
|
||||
<li><a href="http://fedoraproject.org/wiki/FWN/LatestIssue">${_('News')}</a></li>
|
||||
</ul>
|
||||
<!--
|
||||
<div py:if="tg.identity.anonymous" id="language">
|
||||
<!-- TODO: Should this be available to logged in users to (and actually change their DB entry?) -->
|
||||
<form action="${tg.url('/language')}" method="get">
|
||||
<label for="locale">${_('Locale:')}</label>
|
||||
<input type="text" name="locale" id="locale" />
|
||||
<select name="locale" id="locale">
|
||||
<option py:for="language in tg.available_languages" value="${language}" py:attrs="{'selected': tg.lang == language and 'selected' or None}">${language}</option>
|
||||
</select>
|
||||
<input type="submit" value="${_('OK')}" />
|
||||
</form>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<div id="content">
|
||||
<div py:if="tg_flash" class="flash">
|
||||
|
|
|
@ -65,13 +65,10 @@
|
|||
</div>
|
||||
<div class="field">
|
||||
<label for="locale">${_('Locale')}:</label>
|
||||
<input type="text" id="locale" name="locale" value="${target.locale}" />
|
||||
<script type="text/javascript">var hb8 = new HelpBalloon({dataURL: '${tg.url('/help/get_help/user_locale')}'});</script>
|
||||
<!--
|
||||
<select id="locale" name="locale">
|
||||
option py:for="locale in available_locales" value="${locale}" py:attrs="{'selected': target.locale == locale and 'selected' or None}">${locale}</option>
|
||||
<select name="locale" id="locale">
|
||||
<option py:for="language in tg.available_languages" value="${language}" py:attrs="{'selected': tg.lang == language and 'selected' or None}">${language}</option>
|
||||
</select>
|
||||
-->
|
||||
<script type="text/javascript">var hb8 = new HelpBalloon({dataURL: '${tg.url('/help/get_help/user_locale')}'});</script>
|
||||
<!--<script type="text/javascript">var hb7 = new HelpBalloon({dataURL: '${tg.url('/help/get_help/locale')}'});</script>-->
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
|
@ -21,6 +21,7 @@ from fas.model import Log
|
|||
|
||||
from fas import openssl_fas
|
||||
from fas.auth import *
|
||||
from fas.util import available_languages
|
||||
|
||||
from random import Random
|
||||
import sha
|
||||
|
@ -65,9 +66,7 @@ class ValidSSHKey(validators.FancyValidator):
|
|||
return value.file.read()
|
||||
def validate_python(self, value, state):
|
||||
# value = value.file.read()
|
||||
print dir(value)
|
||||
keylines = value.split('\n')
|
||||
print "KEYLINES: %s" % keylines
|
||||
for keyline in keylines:
|
||||
if not keyline:
|
||||
continue
|
||||
|
@ -85,6 +84,15 @@ class ValidUsername(validators.FancyValidator):
|
|||
if re.compile(username_blacklist).match(value):
|
||||
raise validators.Invalid(_("'%s' is an illegal username.") % value, value, state)
|
||||
|
||||
class ValidLanguage(validators.FancyValidator):
|
||||
'''Make sure that a username isn't blacklisted'''
|
||||
def _to_python(self, value, state):
|
||||
return value.strip()
|
||||
def validate_python(self, value, state):
|
||||
if value not in available_languages():
|
||||
raise validators.Invalid(_('The language \'%s\' is not available.') % value, value, state)
|
||||
|
||||
|
||||
class UserSave(validators.Schema):
|
||||
targetname = KnownUser
|
||||
human_name = validators.All(
|
||||
|
@ -96,6 +104,7 @@ class UserSave(validators.Schema):
|
|||
validators.Email(not_empty=True, strip=True, max=128),
|
||||
NonFedoraEmail(not_empty=True, strip=True, max=128),
|
||||
)
|
||||
locale = ValidLanguage(not_empty=True, strip=True)
|
||||
#fedoraPersonBugzillaMail = validators.Email(strip=True, max=128)
|
||||
#fedoraPersonKeyId- Save this one for later :)
|
||||
postal_address = validators.String(max=512)
|
||||
|
@ -236,7 +245,8 @@ class User(controllers.Controller):
|
|||
turbogears.flash(_('You cannot edit %s') % target.username )
|
||||
turbogears.redirect('/user/view/%s', target.username)
|
||||
return dict()
|
||||
return dict(target=target)
|
||||
languages = available_languages()
|
||||
return dict(target=target, languages=languages)
|
||||
|
||||
@identity.require(turbogears.identity.not_anonymous())
|
||||
@validate(validators=UserSave())
|
||||
|
|
16
fas/fas/util.py
Normal file
16
fas/fas/util.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
import os
|
||||
import codecs
|
||||
from turbogears import config
|
||||
from turbogears.i18n.tg_gettext import get_locale_dir
|
||||
|
||||
def available_languages():
|
||||
"""Return available languages for a given domain."""
|
||||
available_languages = []
|
||||
localedir = get_locale_dir()
|
||||
linguas = codecs.open(os.path.join(localedir, 'LINGUAS'), 'r')
|
||||
for lang in linguas.readlines():
|
||||
lang = lang.strip()
|
||||
if lang and not lang.startswith('#'):
|
||||
available_languages.append(lang)
|
||||
return available_languages
|
||||
|
2
fas/po/LINGUAS
Normal file
2
fas/po/LINGUAS
Normal file
|
@ -0,0 +1,2 @@
|
|||
en
|
||||
pl
|
|
@ -4,6 +4,7 @@ import os
|
|||
import re
|
||||
import glob
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
from distutils.command.build import build as _build
|
||||
from distutils.command.install_data import install_data as _install_data
|
||||
|
@ -71,6 +72,13 @@ class Build(_build, object):
|
|||
outf.writelines(line)
|
||||
outf.close()
|
||||
f.close()
|
||||
|
||||
# Make empty en.po
|
||||
dirname = 'locale/'
|
||||
if not os.path.isdir(dirname):
|
||||
os.makedirs(dirname)
|
||||
shutil.copy('po/LINGUAS', 'locale/')
|
||||
|
||||
for pofile in poFiles:
|
||||
# Compile PO files
|
||||
lang = os.path.basename(pofile).rsplit('.', 1)[0]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue