1 """Internationalization support for TurboGears widgets"""
2
3 __all__ = ['LocalizableJSLink', 'CalendarLangFileLink']
4
5 import os
6 import codecs
7 from cherrypy import request
8 from turbogears.i18n import get_locale
9 from turbogears import startup, config
10 from turbogears.util import parse_http_accept_header
11 from turbogears.widgets.base import JSLink, CoreWD, RenderOnlyWD
12
13
15 """Provides a simple way to include language-specific data in your JS code.
16
17 Language file to use is determined from the user's locale or from the 'language'
18 parameter. If there is no language file for the language (determined via
19 'supported_languages' parameter) than 'default_language' is used.
20
21 """
22
23 default_language = 'en'
24 supported_languages = ['en']
25 params = ['default_language', 'language', 'supported_languages']
26 params_doc = {
27 'language': "language code to use "
28 " (overrides user locale setting which is the default)",
29 'default_language': "language code to use"
30 " if specified language is not supported",
31 'supported_languages': "list of supported language codes"
32 " (which means corresponding language files exist)"
33 }
34
41
42
47
48
49 _norm_tag = ''.join([(c.islower() or c.isdigit() or c == '-')
50 and c or c.isupper() and c.lower() or ' ' for c in map(chr, xrange(256))])
51
53 """Normalize string to alphanumeric ascii chars, hyphens and underscores.
54
55 The length is limited to 16 characters and other characters are
56 collapsed to single underscore, or ignored at the start or end.
57
58 """
59 if tag is not None:
60 return '_'.join(str(tag)[:16].translate(_norm_tag).split())
61
62
64 """Normalize the name of a character set."""
65 if charset is not None:
66 charset = norm_tag(charset)
67 try:
68 charset = norm_tag(codecs.lookup(charset).name)
69 except (LookupError, AttributeError):
70
71 pass
72 return charset
73
74
76 """Links to proper calendar.js language file depending on HTTP info."""
77
78 default_charset = 'utf-8'
79
81 languages = parse_http_accept_header(
82 request.headers.get('Accept-Language')) or []
83 language = d.get('language')
84 if language and language != '*':
85 languages.insert(0, language)
86 languages = map(norm_tag, languages)
87 default_language = norm_tag(self.default_language)
88 languages.append(default_language)
89 charsets = parse_http_accept_header(
90 request.headers.get('Accept-Charset')) or []
91 charsets = map(norm_charset, charsets)
92 default_charset = norm_charset(self.default_charset)
93 charset = norm_charset(config.get(self.engine_name == 'kid'
94 and 'kid.encoding' or 'genshi.default_encoding'))
95 if charset and charset != default_charset:
96 charsets.append(charset)
97 charsets.append(default_charset)
98 path = '/tg_widgets/%s' % self.mod
99 base_dir = config.app[path].get('tools.staticdir.dir')
100 base_name = 'calendar/lang/calendar-'
101 def find_link():
102 for lang in languages:
103 if not lang or lang == '*':
104 lang = default_language
105 base_lang = base_name + lang.replace('-', '_')
106 for charset in charsets:
107 if not charset or charset == '*':
108 charset = default_charset
109 file_name = base_lang
110 if charset != default_charset:
111 file_name += '-' + charset.replace('-', '_')
112 file_name += '.js'
113 if os.path.exists(os.path.join(base_dir, file_name)):
114 path = '%s/tg_widgets/%s' % (startup.webpath, self.mod)
115 link = '%s/%s' % (path, file_name)
116 return (link, language, charset)
117 if charset == default_charset:
118 break
119 d['link'], d['language'], d['charset'] = find_link()
120