diff --git a/trac/util/translation.py b/trac/util/translation.py
|
a
|
b
|
|
| 14 | 14 | """Utilities for text translation with gettext.""" |
| 15 | 15 | |
| 16 | 16 | import re |
| | 17 | import sys |
| 17 | 18 | try: |
| 18 | 19 | import threading |
| 19 | 20 | except ImportError: |
| … |
… |
|
| 65 | 66 | def _gettext(): |
| 66 | 67 | trans = get_translations().ugettext(string) |
| 67 | 68 | return kwargs and trans % kwargs or trans |
| | 69 | domain = sys._getframe(1).f_globals.get('domain') |
| | 70 | if domain: |
| | 71 | # It has, use that domain |
| | 72 | return dgettext(domain, string, **kwargs) |
| 68 | 73 | if not hasattr(_current, 'translations'): |
| 69 | 74 | return LazyProxy(_gettext) |
| 70 | 75 | return _gettext() |
| 71 | 76 | _ = gettext |
| | 77 | |
| | 78 | def dgettext(domain, string, **kwargs): |
| | 79 | def _dgettext(): |
| | 80 | trans = get_translations().dugettext(domain, string) |
| | 81 | return kwargs and trans % kwargs or trans |
| | 82 | if not hasattr(_current, 'translations'): |
| | 83 | return LazyProxy(_dgettext) |
| | 84 | return _dgettext() |
| 72 | 85 | |
| 73 | 86 | def ngettext(singular, plural, num, **kwargs): |
| 74 | 87 | kwargs = kwargs.copy() |
| … |
… |
|
| 77 | 90 | if '%(num)' in trans: |
| 78 | 91 | kwargs.update(num=num) |
| 79 | 92 | return kwargs and trans % kwargs or trans |
| | 93 | # The caller is a plugin with domain variable defined ??? |
| | 94 | domain = sys._getframe(1).f_globals.get('domain') |
| | 95 | if domain: |
| | 96 | # It has, use that domain |
| | 97 | return dngettext(domain, singular, plural, num, **kwargs) |
| 80 | 98 | if not hasattr(_current, 'translations'): |
| 81 | 99 | return LazyProxy(_ngettext) |
| 82 | 100 | return _ngettext() |
| | 101 | |
| | 102 | def dngettext(domain, singular, plural, num, **kwargs): |
| | 103 | kwargs = kwargs.copy() |
| | 104 | def _dngettext(): |
| | 105 | trans = get_translations().dungettext(domain, singular, plural, num) |
| | 106 | if '%(num)' in trans: |
| | 107 | kwargs.update(num=num) |
| | 108 | return kwargs and trans % kwargs or trans |
| | 109 | if not hasattr(_current, 'translations'): |
| | 110 | return LazyProxy(_dngettext) |
| | 111 | return _dngettext() |
| 83 | 112 | |
| 84 | 113 | def tgettext(string, **kwargs): |
| 85 | 114 | def _tgettext(): |
| 86 | 115 | trans = get_translations().ugettext(string) |
| 87 | 116 | return kwargs and _tag_kwargs(trans, kwargs) or trans |
| | 117 | # The caller is a plugin with domain variable defined ??? |
| | 118 | domain = sys._getframe(1).f_globals.get('domain') |
| | 119 | if domain: |
| | 120 | # It has, use that domain |
| | 121 | return dtgettext(domain, string, **kwargs) |
| 88 | 122 | if not hasattr(_current, 'translations'): |
| 89 | 123 | return LazyProxy(_tgettext) |
| 90 | 124 | return _tgettext() |
| 91 | 125 | tag_ = tgettext |
| | 126 | |
| | 127 | def dtgettext(domain, string, **kwargs): |
| | 128 | def _dtgettext(): |
| | 129 | trans = get_translations().dugettext(domain, string) |
| | 130 | return kwargs and _tag_kwargs(trans, kwargs) or trans |
| | 131 | if not hasattr(_current, 'translations'): |
| | 132 | return LazyProxy(_dtgettext) |
| | 133 | return _dtgettext() |
| 92 | 134 | |
| 93 | 135 | def tngettext(singular, plural, num, **kwargs): |
| 94 | 136 | kwargs = kwargs.copy() |
| … |
… |
|
| 97 | 139 | if '%(num)' in trans: |
| 98 | 140 | kwargs.update(num=num) |
| 99 | 141 | return kwargs and _tag_kwargs(trans, kwargs) or trans |
| | 142 | # The caller is a plugin with domain variable defined ??? |
| | 143 | domain = sys._getframe(1).f_globals.get('domain') |
| | 144 | if domain: |
| | 145 | # It has, use that domain |
| | 146 | return dtngettext(domain, singular, plural, num, **kwargs) |
| 100 | 147 | if not hasattr(_current, 'translations'): |
| 101 | 148 | return LazyProxy(_tngettext) |
| 102 | 149 | return _tngettext() |
| | 150 | |
| | 151 | def dtngettext(domain, singular, plural, num, **kwargs): |
| | 152 | kwargs = kwargs.copy() |
| | 153 | def _dtngettext(): |
| | 154 | trans = get_translations().dungettext(domain, singular, plural, num) |
| | 155 | if '%(num)' in trans: |
| | 156 | kwargs.update(num=num) |
| | 157 | return kwargs and _tag_kwargs(trans, kwargs) or trans |
| | 158 | if not hasattr(_current, 'translations'): |
| | 159 | return LazyProxy(_dtngettext) |
| | 160 | return _dtngettext() |
| | 161 | |
| | 162 | _plugin_domains = {} |
| 103 | 163 | |
| 104 | | def activate(locale): |
| | 164 | def activate(locale, env_path=None): |
| 105 | 165 | locale_dir = pkg_resources.resource_filename(__name__, '../locale') |
| 106 | 166 | _current.translations = Translations.load(locale_dir, locale) |
| 107 | | |
| | 167 | if env_path: |
| | 168 | plugin_domains = _plugin_domains.get(env_path) |
| | 169 | if plugin_domains: |
| | 170 | for domain, dirname in plugin_domains: |
| | 171 | _current.translations.add_domain(domain, dirname) |
| | 172 | |
| 108 | 173 | _null_translations = NullTranslations() |
| 109 | 174 | |
| 110 | 175 | def get_translations(): |
| … |
… |
|
| 112 | 177 | |
| 113 | 178 | def deactivate(): |
| 114 | 179 | del _current.translations |
| | 180 | |
| | 181 | |
| | 182 | def add_domain(env_path, domain, locales_dir): |
| | 183 | if env_path not in _plugin_domains: |
| | 184 | _plugin_domains[env_path] = [] |
| | 185 | _plugin_domains[env_path].append((domain, locales_dir)) |
| 115 | 186 | |
| 116 | 187 | def get_available_locales(): |
| 117 | 188 | """Return a list of locale identifiers of the locales for which |
diff --git a/trac/web/api.py b/trac/web/api.py
|
a
|
b
|
|
| 339 | 339 | from trac.web.chrome import Chrome |
| 340 | 340 | from trac.util import translation |
| 341 | 341 | if hasattr(self, 'locale'): |
| 342 | | translation.activate(self.locale) |
| | 342 | translation.activate(self.locale, env.path) |
| 343 | 343 | try: |
| 344 | 344 | data = Chrome(env).render_template(self, template, |
| 345 | 345 | data, 'text/html') |
diff --git a/trac/web/chrome.py b/trac/web/chrome.py
|
a
|
b
|
|
| 27 | 27 | |
| 28 | 28 | from genshi import Markup |
| 29 | 29 | from genshi.builder import tag, Element |
| 30 | | from genshi.filters import Translator |
| | 30 | from genshi.filters import Translator, setup_i18n |
| 31 | 31 | from genshi.input import HTML, ParseError |
| 32 | 32 | from genshi.core import Attrs, START |
| 33 | 33 | from genshi.output import DocType |
| … |
… |
|
| 290 | 290 | 'classes': presentation.classes, |
| 291 | 291 | 'date': datetime.date, |
| 292 | 292 | 'datetime': datetime.datetime, |
| | 293 | 'dgettext': translation.dgettext, |
| | 294 | 'dngettext': translation.dngettext, |
| 293 | 295 | 'first_last': presentation.first_last, |
| 294 | 296 | 'get_reporter_id': get_reporter_id, |
| 295 | 297 | 'gettext': translation.gettext, |
| … |
… |
|
| 657 | 659 | """ |
| 658 | 660 | if not self.templates: |
| 659 | 661 | def _template_loaded(template): |
| 660 | | template.filters.insert( |
| 661 | | 0, Translator(translation.get_translations()) |
| 662 | | ) |
| | 662 | translator = Translator(translation.get_translations()) |
| | 663 | setup_i18n(template, translator) |
| 663 | 664 | |
| 664 | 665 | self.templates = TemplateLoader(self.get_all_templates_dirs(), |
| 665 | 666 | auto_reload=self.auto_reload, |
diff --git a/trac/web/main.py b/trac/web/main.py
|
a
|
b
|
|
| 163 | 163 | try: |
| 164 | 164 | try: |
| 165 | 165 | try: |
| 166 | | translation.activate(req.locale) |
| | 166 | translation.activate(req.locale, self.env.path) |
| 167 | 167 | |
| 168 | 168 | # Select the component that should handle the request |
| 169 | 169 | chosen_handler = None |