|
1 """ |
|
2 Internationalization support. |
|
3 """ |
|
4 from django.utils.functional import lazy |
|
5 from django.utils.encoding import force_unicode |
|
6 |
|
7 __all__ = ['gettext', 'gettext_noop', 'gettext_lazy', 'ngettext', |
|
8 'ngettext_lazy', 'string_concat', 'activate', 'deactivate', |
|
9 'get_language', 'get_language_bidi', 'get_date_formats', |
|
10 'get_partial_date_formats', 'check_for_language', 'to_locale', |
|
11 'get_language_from_request', 'templatize', 'ugettext', |
|
12 'ungettext', 'deactivate_all'] |
|
13 |
|
14 # Here be dragons, so a short explanation of the logic won't hurt: |
|
15 # We are trying to solve two problems: (1) access settings, in particular |
|
16 # settings.USE_I18N, as late as possible, so that modules can be imported |
|
17 # without having to first configure Django, and (2) if some other code creates |
|
18 # a reference to one of these functions, don't break that reference when we |
|
19 # replace the functions with their real counterparts (once we do access the |
|
20 # settings). |
|
21 |
|
22 def delayed_loader(*args, **kwargs): |
|
23 """ |
|
24 Replace each real_* function with the corresponding function from either |
|
25 trans_real or trans_null (e.g. real_gettext is replaced with |
|
26 trans_real.gettext or trans_null.gettext). This function is run once, the |
|
27 first time any i18n method is called. It replaces all the i18n methods at |
|
28 once at that time. |
|
29 """ |
|
30 import traceback |
|
31 from django.conf import settings |
|
32 if settings.USE_I18N: |
|
33 import trans_real as trans |
|
34 else: |
|
35 import trans_null as trans |
|
36 caller = traceback.extract_stack(limit=2)[0][2] |
|
37 g = globals() |
|
38 for name in __all__: |
|
39 if hasattr(trans, name): |
|
40 g['real_%s' % name] = getattr(trans, name) |
|
41 |
|
42 # Make the originally requested function call on the way out the door. |
|
43 return g['real_%s' % caller](*args, **kwargs) |
|
44 |
|
45 g = globals() |
|
46 for name in __all__: |
|
47 g['real_%s' % name] = delayed_loader |
|
48 del g, delayed_loader |
|
49 |
|
50 def gettext_noop(message): |
|
51 return real_gettext_noop(message) |
|
52 |
|
53 ugettext_noop = gettext_noop |
|
54 |
|
55 def gettext(message): |
|
56 return real_gettext(message) |
|
57 |
|
58 def ngettext(singular, plural, number): |
|
59 return real_ngettext(singular, plural, number) |
|
60 |
|
61 def ugettext(message): |
|
62 return real_ugettext(message) |
|
63 |
|
64 def ungettext(singular, plural, number): |
|
65 return real_ungettext(singular, plural, number) |
|
66 |
|
67 ngettext_lazy = lazy(ngettext, str) |
|
68 gettext_lazy = lazy(gettext, str) |
|
69 ungettext_lazy = lazy(ungettext, unicode) |
|
70 ugettext_lazy = lazy(ugettext, unicode) |
|
71 |
|
72 def activate(language): |
|
73 return real_activate(language) |
|
74 |
|
75 def deactivate(): |
|
76 return real_deactivate() |
|
77 |
|
78 def get_language(): |
|
79 return real_get_language() |
|
80 |
|
81 def get_language_bidi(): |
|
82 return real_get_language_bidi() |
|
83 |
|
84 def get_date_formats(): |
|
85 return real_get_date_formats() |
|
86 |
|
87 def get_partial_date_formats(): |
|
88 return real_get_partial_date_formats() |
|
89 |
|
90 def check_for_language(lang_code): |
|
91 return real_check_for_language(lang_code) |
|
92 |
|
93 def to_locale(language): |
|
94 return real_to_locale(language) |
|
95 |
|
96 def get_language_from_request(request): |
|
97 return real_get_language_from_request(request) |
|
98 |
|
99 def templatize(src): |
|
100 return real_templatize(src) |
|
101 |
|
102 def deactivate_all(): |
|
103 return real_deactivate_all() |
|
104 |
|
105 def string_concat(*strings): |
|
106 """ |
|
107 Lazy variant of string concatenation, needed for translations that are |
|
108 constructed from multiple parts. |
|
109 """ |
|
110 return u''.join([force_unicode(s) for s in strings]) |
|
111 string_concat = lazy(string_concat, unicode) |