Ticket #4030: 4030_language_info.diff
File 4030_language_info.diff, 20.9 KB (added by , 17 years ago) |
---|
-
django/conf/language_info.py
1 language_info = {'ar': {'bidi': True, 2 'language_code': 'ar', 3 'name': 'Arabic', 4 'name_local': u'Arabic'}, 5 'bg': {'bidi': False, 6 'language_code': 'bg', 7 'name': 'Bulgarian', 8 'name_local': u'\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438'}, 9 'bn': {'bidi': False, 10 'language_code': 'bn', 11 'name': 'Bengali', 12 'name_local': u'\u09ac\u09be\u0982\u09b2\u09be'}, 13 'ca': {'bidi': False, 14 'language_code': 'ca', 15 'name': 'Catalan', 16 'name_local': u'Catal\xe0'}, 17 'cs': {'bidi': False, 18 'language_code': 'cs', 19 'name': 'Czech', 20 'name_local': u'\u010desky'}, 21 'cy': {'bidi': False, 22 'language_code': 'cy', 23 'name': 'Welsh', 24 'name_local': u'Cymraeg'}, 25 'da': {'bidi': False, 26 'language_code': 'da', 27 'name': 'Danish', 28 'name_local': u'Dansk'}, 29 'de': {'bidi': False, 30 'language_code': 'de', 31 'name': 'German', 32 'name_local': u'Deutsch'}, 33 'el': {'bidi': False, 34 'language_code': 'el', 35 'name': 'Greek', 36 'name_local': u'\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac'}, 37 'en': {'bidi': False, 38 'language_code': 'en', 39 'name': 'English', 40 'name_local': u'English'}, 41 'es': {'bidi': False, 42 'language_code': 'es', 43 'name': 'Spanish', 44 'name_local': u'Espa\xf1ol'}, 45 'es-ar': {'bidi': False, 46 'language_code': 'es-ar', 47 'name': 'Argentinean Spanish', 48 'name_local': u'Espa\xf1ol Argentino'}, 49 'eu': {'bidi': False, 50 'language_code': 'eu', 51 'name': 'Basque', 52 'name_local': u'Basque'}, 53 'fa': {'bidi': True, 54 'language_code': 'fa', 55 'name': 'Persian', 56 'name_local': u'Persian'}, 57 'fi': {'bidi': False, 58 'language_code': 'fi', 59 'name': 'Finnish', 60 'name_local': u'suomi'}, 61 'fr': {'bidi': False, 62 'language_code': 'fr', 63 'name': 'French', 64 'name_local': u'Fran\xe7ais'}, 65 'ga': {'bidi': False, 66 'language_code': 'ga', 67 'name': 'Irish', 68 'name_local': u'Irish'}, 69 'gl': {'bidi': False, 70 'language_code': 'gl', 71 'name': 'Galician', 72 'name_local': u'galego'}, 73 'he': {'bidi': True, 74 'language_code': 'he', 75 'name': 'Hebrew', 76 'name_local': u'\u05e2\u05d1\u05e8\u05d9\u05ea - Hebrew'}, 77 'hr': {'bidi': False, 78 'language_code': 'hr', 79 'name': 'Croatian', 80 'name_local': u'Hrvatski'}, 81 'hu': {'bidi': False, 82 'language_code': 'hu', 83 'name': 'Hungarian', 84 'name_local': u'Magyar'}, 85 'is': {'bidi': False, 86 'language_code': 'is', 87 'name': 'Icelandic', 88 'name_local': u'\xcdslenska'}, 89 'it': {'bidi': False, 90 'language_code': 'it', 91 'name': 'Italian', 92 'name_local': u'Italiano'}, 93 'ja': {'bidi': False, 94 'language_code': 'ja', 95 'name': 'Japanese', 96 'name_local': u'\u65e5\u672c\u8a9e'}, 97 'ka': {'bidi': False, 98 'language_code': 'ka', 99 'name': 'Georgian', 100 'name_local': u'\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8'}, 101 'km': {'bidi': False, 102 'language_code': 'km', 103 'name': 'Khmer', 104 'name_local': u'Khmer'}, 105 'kn': {'bidi': False, 106 'language_code': 'kn', 107 'name': 'Kannada', 108 'name_local': u'Kannada'}, 109 'ko': {'bidi': False, 110 'language_code': 'ko', 111 'name': 'Korean', 112 'name_local': u'\ud55c\uad6d\uc5b4'}, 113 'lv': {'bidi': False, 114 'language_code': 'lv', 115 'name': 'Latvian', 116 'name_local': u'Latvie\u0161u'}, 117 'mk': {'bidi': False, 118 'language_code': 'mk', 119 'name': 'Macedonian', 120 'name_local': u'\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438'}, 121 'nl': {'bidi': False, 122 'language_code': 'nl', 123 'name': 'Dutch', 124 'name_local': u'Nederlands'}, 125 'no': {'bidi': False, 126 'language_code': 'no', 127 'name': 'Norwegian', 128 'name_local': u'Norsk'}, 129 'pl': {'bidi': False, 130 'language_code': 'pl', 131 'name': 'Polish', 132 'name_local': u'Polski'}, 133 'pt': {'bidi': False, 134 'language_code': 'pt', 135 'name': 'Portugese', 136 'name_local': u'Portugese'}, 137 'pt-br': {'bidi': False, 138 'language_code': 'pt-br', 139 'name': 'Brazilian Portuguese', 140 'name_local': u'Portugu\xeas Brasileiro'}, 141 'ro': {'bidi': False, 142 'language_code': 'ro', 143 'name': 'Romanian', 144 'name_local': u'Romana'}, 145 'ru': {'bidi': False, 146 'language_code': 'ru', 147 'name': 'Russian', 148 'name_local': u'\u0420\u0443\u0441\u0441\u043a\u0438\u0439'}, 149 'sk': {'bidi': False, 150 'language_code': 'sk', 151 'name': 'Slovak', 152 'name_local': u'Slovensky'}, 153 'sl': {'bidi': False, 154 'language_code': 'sl', 155 'name': 'Slovenian', 156 'name_local': u'Slovenski'}, 157 'sr': {'bidi': False, 158 'language_code': 'sr', 159 'name': 'Serbian', 160 'name_local': u'Srpski'}, 161 'sv': {'bidi': False, 162 'language_code': 'sv', 163 'name': 'Swedish', 164 'name_local': u'Svenska'}, 165 'ta': {'bidi': False, 166 'language_code': 'ta', 167 'name': 'Tamil', 168 'name_local': u'\u0ba4\u0bae\u0bbf\u0bb4\u0bcd'}, 169 'te': {'bidi': False, 170 'language_code': 'te', 171 'name': 'Telugu', 172 'name_local': u'Telugu'}, 173 'tr': {'bidi': False, 174 'language_code': 'tr', 175 'name': 'Turkish', 176 'name_local': u'T\xfcrk\xe7e'}, 177 'uk': {'bidi': False, 178 'language_code': 'uk', 179 'name': 'Ukrainian', 180 'name_local': u'Ukrainian'}, 181 'zh-cn': {'bidi': False, 182 'language_code': 'zh-cn', 183 'name': 'Simplified Chinese', 184 'name_local': u'\u7b80\u4f53\u4e2d\u6587'}, 185 'zh-tw': {'bidi': False, 186 'language_code': 'zh-tw', 187 'name': 'Traditional Chinese', 188 'name_local': u'\u7e41\u9ad4\u4e2d\u6587'}} -
django/templatetags/i18n.py
Property changes on: django/conf/language_info.py ___________________________________________________________________ Name: svn:eol-style + native
17 17 context[self.variable] = [(k, translation.ugettext(v)) for k, v in settings.LANGUAGES] 18 18 return '' 19 19 20 class GetLanguageInfoNode(Node): 21 def __init__(self, lang_code, variable): 22 self.lang_code = Variable(lang_code) 23 self.variable = variable 24 25 def render(self, context): 26 lang_code = self.lang_code.resolve(context) 27 context[self.variable] = translation.get_language_info(lang_code) 28 return '' 29 30 class GetLanguageInfoListNode(Node): 31 def __init__(self, languages, variable): 32 self.languages = Variable(languages) 33 self.variable = variable 34 35 def get_language_info(self, language): 36 # ``language`` is either a language code string or a sequence with the 37 # language code as its first item 38 if len(language[0]) > 1: 39 return translation.get_language_info(language[0]) 40 else: 41 return translation.get_language_info(str(language)) 42 43 def render(self, context): 44 languages = self.languages.resolve(context) 45 context[self.variable] = [self.get_language_info(l) for l in languages] 46 return '' 47 20 48 class GetCurrentLanguageNode(Node): 21 49 def __init__(self, variable): 22 50 self.variable = variable … … 107 135 raise TemplateSyntaxError, "'get_available_languages' requires 'as variable' (got %r)" % args 108 136 return GetAvailableLanguagesNode(args[2]) 109 137 138 def do_get_language_info(parser, token): 139 """ 140 This will store the language information dictionary for the given language 141 code in a context variable. 142 143 Usage:: 144 145 {% get_language_info for language_code as l %} 146 {{ l.language_code }} 147 {{ l.name }} 148 {{ l.name_local }} 149 {{ l.bidi|yesno:"bi-directional,uni-directional" }} 150 """ 151 args = token.contents.split() 152 if len(args) != 5 or args[1] != 'for' or args[3] != 'as': 153 raise TemplateSyntaxError, "'%s' requires 'for string as variable' (got %r)" % (args[0], args[1:]) 154 return GetLanguageInfoNode(args[2], args[4]) 155 156 def do_get_language_info_list(parser, token): 157 """ 158 This will store a list of language information dictionaries for the given 159 language codes in a context variable. The language codes can be specified 160 ither as a list of strings or a settings.LANGUAGES style tuple (or any 161 sequence of sequences whose first items are language codes). 162 163 Usage:: 164 165 {% get_language_info_list for LANGUAGES as langs %} 166 {% for l in langs %} 167 {{ l.language_code }} 168 {{ l.name }} 169 {{ l.name_local }} 170 {{ l.bidi|yesno:"bi-directional,uni-directional" }} 171 {% endfor %} 172 """ 173 args = token.contents.split() 174 if len(args) != 5 or args[1] != 'for' or args[3] != 'as': 175 raise TemplateSyntaxError, "'%s' requires 'for sequence as variable' (got %r)" % (args[0], args[1:]) 176 return GetLanguageInfoListNode(args[2], args[4]) 177 178 def language_name(lang_code): 179 return translation.get_language_info(lang_code)['name'] 180 181 def language_name_local(lang_code): 182 return translation.get_language_info(lang_code)['name_local'] 183 184 def language_bidi(lang_code): 185 return translation.get_language_info(lang_code)['bidi'] 186 110 187 def do_get_current_language(parser, token): 111 188 """ 112 189 This will store the current language in the context. … … 253 330 counter) 254 331 255 332 register.tag('get_available_languages', do_get_available_languages) 333 register.tag('get_language_info', do_get_language_info) 334 register.tag('get_language_info_list', do_get_language_info_list) 256 335 register.tag('get_current_language', do_get_current_language) 257 336 register.tag('get_current_language_bidi', do_get_current_language_bidi) 258 337 register.tag('trans', do_translate) 259 338 register.tag('blocktrans', do_block_translate) 339 340 register.filter(language_name) 341 register.filter(language_name_local) 342 register.filter(language_bidi) -
django/utils/translation/__init__.py
3 3 """ 4 4 from django.utils.functional import lazy 5 5 from django.utils.encoding import force_unicode 6 try: 7 from django.conf.language_info import language_info 8 except ImportError: 9 language_info = {} 10 from warnings import warn 11 warn("Module django.conf.language_info not found. Run django/bin/make-language-info.py to generate it and improve performance.") 6 12 7 13 __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext', 8 14 'ngettext_lazy', 'string_concat', 'activate', 'deactivate', … … 109 115 """ 110 116 return u''.join([force_unicode(s) for s in strings]) 111 117 string_concat = lazy(string_concat, unicode) 118 119 def get_language_info(lang_code): 120 if lang_code not in language_info: 121 from django.conf import settings 122 for code, name in settings.LANGUAGES: 123 if code == lang_code: 124 old_lang = get_language() 125 activate(lang_code) 126 info = {"language_code": lang_code, 127 "name": name, 128 "name_local": ugettext(name), 129 "bidi": lang_code in settings.LANGUAGES_BIDI} 130 activate(old_lang) 131 language_info[lang_code] = info 132 break 133 else: 134 raise KeyError("Unknown language code %r." % lang_code) 135 return language_info[lang_code] -
django/bin/make-language-info.py
1 #!/usr/bin/env python 2 3 LANGUAGE_INFO_PY_FILE = 'django/conf/language_info.py' 4 5 # Need to ensure that the i18n framework is enabled 6 from django.conf import settings 7 settings.configure(USE_I18N = True) 8 9 # Don't display the import warning about the missing language info file 10 import warnings 11 warnings.filterwarnings('ignore', category=UserWarning) 12 13 from django.utils import translation 14 from pprint import pformat 15 16 def make_language_info(): 17 language_info = {} 18 for code, name in settings.LANGUAGES: 19 translation.activate(code) 20 language_info[code] = translation.get_language_info(code) 21 from os.path import join, dirname, abspath 22 target = abspath(join(dirname(__file__), '..', '..', LANGUAGE_INFO_PY_FILE)) 23 print 'Writing language information to\n%s' % target 24 file(target, 'w').write('language_info = %s\n' % pformat(language_info)) 25 print 'Done.' 26 27 28 if __name__ == "__main__": 29 make_language_info() -
tests/regressiontests/i18n/language_info.py
Property changes on: django/bin/make-language-info.py ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native
1 tests = """ 2 >>> from django.utils.translation import get_language_info 3 >>> from pprint import pprint 4 >>> pprint(get_language_info('de')) 5 {'bidi': False, 6 'language_code': 'de', 7 'name': 'German', 8 'name_local': u'Deutsch'} 9 """ -
tests/regressiontests/i18n/tests.py
Property changes on: tests/regressiontests/i18n/language_info.py ___________________________________________________________________ Name: svn:eol-style + native
1 1 # coding: utf-8 2 import misc 2 import misc, language_info 3 3 4 4 regressions = ur""" 5 5 Format string interpolation should work with *_lazy objects. … … 68 68 69 69 __test__ = { 70 70 'regressions': regressions, 71 'language_info': language_info.tests, 71 72 'misc': misc.tests, 72 73 } -
tests/regressiontests/templates/tests.py
755 755 'i18n17': ('{% load i18n %}{% blocktrans with anton|escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 756 756 'i18n18': ('{% load i18n %}{% blocktrans with anton|force_escape as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'α & β'}, u'α & β'), 757 757 758 # retrieving language information 759 'i18n19': ('{% load i18n %}{% get_language_info for "de" as l %}{{ l.language_code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}', {}, 'de: German/Deutsch bidi=False'), 760 'i18n20': ('{% load i18n %}{% get_language_info for LANGUAGE_CODE as l %}{{ l.language_code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}', {'LANGUAGE_CODE': 'fi'}, 'fi: Finnish/suomi bidi=False'), 761 'i18n21': ('{% load i18n %}{% get_language_info_list for langcodes as langs %}{% for l in langs %}{{ l.language_code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}; {% endfor %}', {'langcodes': ['it', 'no']}, 'it: Italian/Italiano bidi=False; no: Norwegian/Norsk bidi=False; '), 762 'i18n22': ('{% load i18n %}{% get_language_info_list for langcodes as langs %}{% for l in langs %}{{ l.language_code }}: {{ l.name }}/{{ l.name_local }} bidi={{ l.bidi }}; {% endfor %}', {'langcodes': (('sl', 'Slovenian'), ('fa', 'Persian'))}, 'sl: Slovenian/Slovenski bidi=False; fa: Persian/Persian bidi=True; '), 763 'i18n23': ('{% load i18n %}{{ "hu"|language_name }} {{ "hu"|language_name_local }} {{ "hu"|language_bidi }}', {}, 'Hungarian Magyar False'), 764 'i18n24': ('{% load i18n %}{{ langcode|language_name }} {{ langcode|language_name_local }} {{ langcode|language_bidi }}', {'langcode': 'nl'}, 'Dutch Nederlands False'), 765 758 766 ### HANDLING OF TEMPLATE_STRING_IF_INVALID ################################### 759 767 760 768 'invalidstr01': ('{{ var|default:"Foo" }}', {}, ('Foo','INVALID')), -
docs/i18n.txt
266 266 Each ``RequestContext`` has access to three translation-specific variables: 267 267 268 268 * ``LANGUAGES`` is a list of tuples in which the first element is the 269 language code and the second is the language name (in that language).269 language code and the second is the language name (in English). 270 270 * ``LANGUAGE_CODE`` is the current user's preferred language, as a string. 271 271 Example: ``en-us``. (See "How language preference is discovered", below.) 272 272 * ``LANGUAGE_BIDI`` is the current language's direction. If True, it's a … … 640 640 .. _session: ../sessions/ 641 641 .. _request object: ../request_response/#httprequest-objects 642 642 643 Local names of languages 644 ======================== 645 646 The ``get_language_info()`` function provides detailed information about 647 languages:: 648 649 >>> form django.utils.translation import get_language_info 650 >>> l = get_language_info('de') 651 >>> print l['name'], l['name_local'], l['bidi'] 652 German Deutsch False 653 654 The ``name`` and ``name_local`` attributes of the dictionary contain the name 655 of the language in English and the language itself, respectively. The ``bidi`` 656 attribute is True only for bi-directional languages. 657 658 In templates, you can use special template tags or filters to retrieve the same 659 information. To get information about a single language, use the 660 ``{% get_language_info %}`` tag:: 661 662 {% get_language_info for LANGUAGE_CODE as lang %} 663 {% get_language_info for "pl" as lang %} 664 665 You can then access the information:: 666 667 Language code: {{ lang.language_code }}<br /> 668 Name of language: {{ lang.name_local }}<br /> 669 Name in English: {{ lang.name }}<br /> 670 Bi-directional: {{ lang.bidi }} 671 672 You can also use the ``{% get_language_info_list %}`` template tag to retrieve 673 information for a list of languages (e.g. active languages as specified in 674 ``settings.LANGUAGES``). See `The set_language redirect view`_ for an example 675 of how to display a language selector using ``{% get_language_info_list %}``. 676 677 In addition to ``settings.LANGUAGES`` style nested tuples, 678 ``{% get_language_info_list %}`` supports simple lists of language codes. If 679 you do this in your view:: 680 681 return render_to_response('mytemplate.html', 682 {'available_languages': ['en', 'es', 'fr']}, 683 RequestContext(request)) 684 685 you can iterate those languages in the template:: 686 687 {% get_language_info_list available_languages %} 688 {% for l in available_languages %} ... {% endfor %} 689 690 There are also simple filters available for convenience: 691 692 * ``{{ LANGUAGE_CODE|language_name }}`` ("German") 693 * ``{{ LANGUAGE_CODE|language_name_local }}`` ("Deutsch") 694 * ``{{ LANGUAGE_CODE|bidi }}`` (False) 695 696 The source of the language information is the ``django.conf.language_info`` 697 module. If you add a new translation, you can run the 698 ``django/bin/make-language-info.py`` script to insert the information for the 699 added language. 700 643 701 Using translations in your own projects 644 702 ======================================= 645 703 … … 732 790 * If that's empty -- say, if a user's browser suppresses that header -- 733 791 then the user will be redirected to ``/`` (the site root) as a fallback. 734 792 735 Here's example HTML template code:: 793 Here's example HTML template code (see `Local names of languages`_ for more 794 information):: 736 795 796 {% get_language_info_list for LANGUAGES as available_languages %} 737 797 <form action="/i18n/setlang/" method="post"> 738 <input name="next" type="hidden" value="/next/page/" /> 739 <select name="language"> 740 {% for lang in LANGUAGES %} 741 <option value="{{ lang.0 }}">{{ lang.1 }}</option> 742 {% endfor %} 743 </select> 744 <input type="submit" value="Go" /> 798 <input name="next" type="hidden" value="/next/page/" /> 799 <select name="language"> 800 {% for lang in available_languages %} 801 <option value="{{ lang.language_code }}" {% ifequal lang.language_code LANGUAGE_CODE %}selected{% endifequal %}> 802 {{ lang.name_local }} 803 </option> 804 {% endfor %} 805 </select> 806 <input type="submit" value="Go" /> 745 807 </form> 746 808 747 809 Translations and JavaScript