diff --git a/django/bin/compile-messages.py b/django/bin/compile-messages.py index 30a92737d8..7e5be279f6 100755 --- a/django/bin/compile-messages.py +++ b/django/bin/compile-messages.py @@ -4,21 +4,24 @@ import os import sys import getopt -basedir = None +def compile_messages(): + basedir = None -if os.path.isdir(os.path.join('conf', 'locale')): - basedir = os.path.abspath(os.path.join('conf', 'locale')) -elif os.path.isdir('locale'): - basedir = os.path.abspath('locale') -else: - print "this script should be run from the django svn tree or your project or app tree" - sys.exit(1) + if os.path.isdir(os.path.join('conf', 'locale')): + basedir = os.path.abspath(os.path.join('conf', 'locale')) + elif os.path.isdir('locale'): + basedir = os.path.abspath('locale') + else: + print "this script should be run from the django svn tree or your project or app tree" + sys.exit(1) -for (dirpath, dirnames, filenames) in os.walk(basedir): - for file in filenames: - if file.endswith('.po'): - sys.stderr.write('processing file %s in %s\n' % (file, dirpath)) - pf = os.path.splitext(os.path.join(dirpath, file))[0] - cmd = 'msgfmt -o "%s.mo" "%s.po"' % (pf, pf) - os.system(cmd) + for (dirpath, dirnames, filenames) in os.walk(basedir): + for file in filenames: + if file.endswith('.po'): + sys.stderr.write('processing file %s in %s\n' % (file, dirpath)) + pf = os.path.splitext(os.path.join(dirpath, file))[0] + cmd = 'msgfmt -o "%s.mo" "%s.po"' % (pf, pf) + os.system(cmd) +if __name__ == "__main__": + compile_messages() diff --git a/django/bin/make-messages.py b/django/bin/make-messages.py index bb43ca2f9b..600799858f 100755 --- a/django/bin/make-messages.py +++ b/django/bin/make-messages.py @@ -1,139 +1,141 @@ #!/usr/bin/python +from django.utils.translation import templateize import re import os import sys import getopt -from django.utils.translation import templateize - pythonize_re = re.compile(r'\n\s*//') -localedir = None +def make_messages(): + localedir = None -if os.path.isdir(os.path.join('conf', 'locale')): - localedir = os.path.abspath(os.path.join('conf', 'locale')) -elif os.path.isdir('locale'): - localedir = os.path.abspath('locale') -else: - print "This script should be run from the django svn tree or your project or app tree." - print "If you did indeed run it from the svn checkout or your project or application," - print "maybe you are just missing the conf/locale (in the django tree) or locale (for project" - print "and application) directory?" - print "make-messages.py doesn't create it automatically, you have to create it by hand if" - print "you want to enable i18n for your project or application." - sys.exit(1) + if os.path.isdir(os.path.join('conf', 'locale')): + localedir = os.path.abspath(os.path.join('conf', 'locale')) + elif os.path.isdir('locale'): + localedir = os.path.abspath('locale') + else: + print "This script should be run from the django svn tree or your project or app tree." + print "If you did indeed run it from the svn checkout or your project or application," + print "maybe you are just missing the conf/locale (in the django tree) or locale (for project" + print "and application) directory?" + print "make-messages.py doesn't create it automatically, you have to create it by hand if" + print "you want to enable i18n for your project or application." + sys.exit(1) -(opts, args) = getopt.getopt(sys.argv[1:], 'l:d:va') + (opts, args) = getopt.getopt(sys.argv[1:], 'l:d:va') -lang = None -domain = 'django' -verbose = False -all = False + lang = None + domain = 'django' + verbose = False + all = False -for o, v in opts: - if o == '-l': - lang = v - elif o == '-d': - domain = v - elif o == '-v': - verbose = True - elif o == '-a': - all = True + for o, v in opts: + if o == '-l': + lang = v + elif o == '-d': + domain = v + elif o == '-v': + verbose = True + elif o == '-a': + all = True -if domain not in ('django', 'djangojs'): - print "currently make-messages.py only supports domains 'django' and 'djangojs'" - sys.exit(1) -if (lang is None and not all) or domain is None: - print "usage: make-messages.py -l " - print " or: make-messages.py -a" - sys.exit(1) + if domain not in ('django', 'djangojs'): + print "currently make-messages.py only supports domains 'django' and 'djangojs'" + sys.exit(1) + if (lang is None and not all) or domain is None: + print "usage: make-messages.py -l " + print " or: make-messages.py -a" + sys.exit(1) -languages = [] + languages = [] -if lang is not None: - languages.append(lang) -elif all: - languages = [el for el in os.listdir(localedir) if not el.startswith('.')] + if lang is not None: + languages.append(lang) + elif all: + languages = [el for el in os.listdir(localedir) if not el.startswith('.')] -for lang in languages: + for lang in languages: - print "processing language", lang - basedir = os.path.join(localedir, lang, 'LC_MESSAGES') - if not os.path.isdir(basedir): - os.makedirs(basedir) + print "processing language", lang + basedir = os.path.join(localedir, lang, 'LC_MESSAGES') + if not os.path.isdir(basedir): + os.makedirs(basedir) - pofile = os.path.join(basedir, '%s.po' % domain) - potfile = os.path.join(basedir, '%s.pot' % domain) + pofile = os.path.join(basedir, '%s.po' % domain) + potfile = os.path.join(basedir, '%s.pot' % domain) - if os.path.exists(potfile): - os.unlink(potfile) + if os.path.exists(potfile): + os.unlink(potfile) - for (dirpath, dirnames, filenames) in os.walk("."): - for file in filenames: - if domain == 'djangojs' and file.endswith('.js'): - if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) - src = open(os.path.join(dirpath, file), "rb").read() - src = pythonize_re.sub('\n#', src) - open(os.path.join(dirpath, '%s.py' % file), "wb").write(src) - thefile = '%s.py' % file - cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy -o - "%s"' % ( - os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) - (stdin, stdout, stderr) = os.popen3(cmd, 'b') - msgs = stdout.read() - errors = stderr.read() - if errors: - print "errors happened while running xgettext on %s" % file - print errors - sys.exit(8) - old = '#: '+os.path.join(dirpath, thefile)[2:] - new = '#: '+os.path.join(dirpath, file)[2:] - msgs = msgs.replace(old, new) - if msgs: - open(potfile, 'ab').write(msgs) - os.unlink(os.path.join(dirpath, thefile)) - elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')): - thefile = file - if file.endswith('.html'): + for (dirpath, dirnames, filenames) in os.walk("."): + for file in filenames: + if domain == 'djangojs' and file.endswith('.js'): + if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) src = open(os.path.join(dirpath, file), "rb").read() - open(os.path.join(dirpath, '%s.py' % file), "wb").write(templateize(src)) + src = pythonize_re.sub('\n#', src) + open(os.path.join(dirpath, '%s.py' % file), "wb").write(src) thefile = '%s.py' % file - if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) - cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy -o - "%s"' % ( - os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) - (stdin, stdout, stderr) = os.popen3(cmd, 'b') - msgs = stdout.read() - errors = stderr.read() - if errors: - print "errors happened while running xgettext on %s" % file - print errors - sys.exit(8) - if thefile != file: + cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy -o - "%s"' % ( + os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) + (stdin, stdout, stderr) = os.popen3(cmd, 'b') + msgs = stdout.read() + errors = stderr.read() + if errors: + print "errors happened while running xgettext on %s" % file + print errors + sys.exit(8) old = '#: '+os.path.join(dirpath, thefile)[2:] new = '#: '+os.path.join(dirpath, file)[2:] msgs = msgs.replace(old, new) - if msgs: - open(potfile, 'ab').write(msgs) - if thefile != file: + if msgs: + open(potfile, 'ab').write(msgs) os.unlink(os.path.join(dirpath, thefile)) + elif domain == 'django' and (file.endswith('.py') or file.endswith('.html')): + thefile = file + if file.endswith('.html'): + src = open(os.path.join(dirpath, file), "rb").read() + open(os.path.join(dirpath, '%s.py' % file), "wb").write(templateize(src)) + thefile = '%s.py' % file + if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath)) + cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy -o - "%s"' % ( + os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile)) + (stdin, stdout, stderr) = os.popen3(cmd, 'b') + msgs = stdout.read() + errors = stderr.read() + if errors: + print "errors happened while running xgettext on %s" % file + print errors + sys.exit(8) + if thefile != file: + old = '#: '+os.path.join(dirpath, thefile)[2:] + new = '#: '+os.path.join(dirpath, file)[2:] + msgs = msgs.replace(old, new) + if msgs: + open(potfile, 'ab').write(msgs) + if thefile != file: + os.unlink(os.path.join(dirpath, thefile)) - if os.path.exists(potfile): - (stdin, stdout, stderr) = os.popen3('msguniq "%s"' % potfile, 'b') - msgs = stdout.read() - errors = stderr.read() - if errors: - print "errors happened while running msguniq" - print errors - sys.exit(8) - open(potfile, 'w').write(msgs) - if os.path.exists(pofile): - (stdin, stdout, stderr) = os.popen3('msgmerge -q "%s" "%s"' % (pofile, potfile), 'b') + if os.path.exists(potfile): + (stdin, stdout, stderr) = os.popen3('msguniq "%s"' % potfile, 'b') msgs = stdout.read() errors = stderr.read() if errors: - print "errors happened while running msgmerge" + print "errors happened while running msguniq" print errors sys.exit(8) - open(pofile, 'wb').write(msgs) - os.unlink(potfile) + open(potfile, 'w').write(msgs) + if os.path.exists(pofile): + (stdin, stdout, stderr) = os.popen3('msgmerge -q "%s" "%s"' % (pofile, potfile), 'b') + msgs = stdout.read() + errors = stderr.read() + if errors: + print "errors happened while running msgmerge" + print errors + sys.exit(8) + open(pofile, 'wb').write(msgs) + os.unlink(potfile) +if __name__ == "__main__": + make_messages() diff --git a/django/bin/unique-messages.py b/django/bin/unique-messages.py index 9e88b87065..c85561ca29 100755 --- a/django/bin/unique-messages.py +++ b/django/bin/unique-messages.py @@ -4,23 +4,26 @@ import os import sys import getopt -basedir = None +def unique_messages(): + basedir = None -if os.path.isdir(os.path.join('conf', 'locale')): - basedir = os.path.abspath(os.path.join('conf', 'locale')) -elif os.path.isdir('locale'): - basedir = os.path.abspath('locale') -else: - print "this script should be run from the django svn tree or your project or app tree" - sys.exit(1) + if os.path.isdir(os.path.join('conf', 'locale')): + basedir = os.path.abspath(os.path.join('conf', 'locale')) + elif os.path.isdir('locale'): + basedir = os.path.abspath('locale') + else: + print "this script should be run from the django svn tree or your project or app tree" + sys.exit(1) -for (dirpath, dirnames, filenames) in os.walk(basedir): - for file in filenames: - if file.endswith('.po'): - sys.stderr.write('processing file %s in %s\n' % (file, dirpath)) - pf = os.path.splitext(os.path.join(dirpath, file))[0] - cmd = 'msguniq "%s.po"' % pf - stdout = os.popen(cmd) - msg = stdout.read() - open('%s.po' % pf, 'w').write(msg) + for (dirpath, dirnames, filenames) in os.walk(basedir): + for file in filenames: + if file.endswith('.po'): + sys.stderr.write('processing file %s in %s\n' % (file, dirpath)) + pf = os.path.splitext(os.path.join(dirpath, file))[0] + cmd = 'msguniq "%s.po"' % pf + stdout = os.popen(cmd) + msg = stdout.read() + open('%s.po' % pf, 'w').write(msg) +if __name__ == "__main__": + unique_messages() diff --git a/docs/i18n.txt b/docs/i18n.txt index 9e7cccad8b..782f6a4ffc 100644 --- a/docs/i18n.txt +++ b/docs/i18n.txt @@ -447,6 +447,24 @@ Notes: en-us). .. _LANGUAGES setting: http://www.djangoproject.com/documentation/settings/#languages + * the LocaleMiddleware can only select languages for which there is a + django provided base translation. If you want to provide translations + for your application that aren't already in the set of translations + in Djangos source tree, you will want to at least provide basic + translations for that language. For example Django uses technical + message IDs to translate date formats and time formats - so you will + need at least those translations for the system to work correctly. + + A good starting point is to just copy over the english ``.po`` file + and to translate at least the technical messages and maybe the validator + messages, too. + + Technical message IDs are easily recognized by them being all upper case. + You don't translate the message ID as with other messages, you provide + the correct local variant on the provided english value. For example with + ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``), this would + be the format string that you want to use in your language. The format + is identical to the ``now`` tag date formattings. Once ``LocaleMiddleware`` determines the user's preference, it makes this preference available as ``request.LANGUAGE_CODE`` for each `request object`_. diff --git a/docs/templates_python.txt b/docs/templates_python.txt index aeedfdc614..bde36cb037 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -285,7 +285,7 @@ optional, third positional argument, ``processors``. In this example, the Here's what each of the default processors does: .. _HttpRequest object: http://www.djangoproject.com/documentation/request_response/#httprequest-objects -.. _TEMPLATE_CONTEXT_PROCESSORS setting: http://www.djangoproject.com/documentation/settings/#template-context_processors +.. _TEMPLATE_CONTEXT_PROCESSORS setting: http://www.djangoproject.com/documentation/settings/#template-context-processors django.core.context_processors.auth ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~