Edgewall Software

Ticket #6353: trac-jsi18n.patch

File trac-jsi18n.patch, 5.1 KB (added by jonas, 2 months ago)

A first prototype for i18n support for javascript

  • setup.py

     
    2121    extra['message_extractors'] = { 
    2222        'trac': [ 
    2323            ('**.py',                'python', None), 
     24            ('**.js',                'javascript', None), 
    2425            ('**/templates/**.html', 'genshi', None), 
    2526            ('**/templates/**.txt',  'genshi', { 
    2627                'template_class': 'genshi.template:TextTemplate' 
  • trac/htdocs/js/blame.js

     
    7474            message = $('<div class="message">').css("position", "absolute") 
    7575                .append($('<div class="inlinebuttons">') 
    7676                  .append($('<input value="Close" type="button">').click(hide))) 
    77                 .append($('<div>').html(data || "<strong>(no changeset information)</strong>")) 
     77                .append($('<div>').html(data || "<strong>" + _("(no changeset information)") + "</strong>")) 
    7878              .appendTo("body"); 
    7979 
    8080            // workaround non-clickable "Close" issue in Firefox 
  • trac/templates/jsi18ncatalog.js

     
     1var _c = {}; 
     2#for msgid, string in catalog._catalog.items() 
     3#choose 
     4#when msgid == '' 
     5#end 
     6#when isinstance(msgid, (list, tuple)) 
     7  _c['${javascript_quote(msgid[0])}', ${msgid[1] and 'true' or 'false'}] = '${javascript_quote(string)}'; 
     8#end 
     9#otherwise 
     10  _c['${javascript_quote(msgid)}'] = '${javascript_quote(string)}'; 
     11#end 
     12#end 
     13#end 
     14 
     15function gettext(msgid) { 
     16    var value = _c[msgid]; 
     17    if(typeof(value) == 'undefined') { 
     18        return msgid; 
     19    } 
     20    else { 
     21        return value; 
     22    } 
     23} 
     24_ = gettext; 
     25 
  • trac/web/chrome.py

     
    4343from trac.util.compat import partial 
    4444from trac.util.html import plaintext 
    4545from trac.util.text import pretty_size, obfuscate_email_address, \ 
    46                            shorten_line, unicode_quote_plus, to_unicode 
     46                           shorten_line, unicode_quote_plus, to_unicode, \ 
     47                           javascript_quote 
    4748from trac.util.datefmt import pretty_timedelta, format_datetime, format_date, \ 
    4849                              format_time, http_date, utc 
    49 from trac.util.translation import _ 
     50from trac.util.translation import _, get_translations 
    5051from trac.web.api import IRequestHandler, ITemplateStreamFilter, HTTPNotFound 
    5152from trac.web.href import Href 
    5253from trac.wiki import IWikiSyntaxProvider 
     
    427428            def __init__(self, req): 
    428429                self.base_path = req.base_path 
    429430                self.chrome = chrome 
     431                self.href = req.href 
    430432        fakereq = FakeRequest(req) 
    431433 
    432434        htdocs_location = self.htdocs_location or req.href.chrome('common') 
     
    444446            add_script(fakereq, 'common/js/noconflict.js') 
    445447        add_script(fakereq, 'common/js/trac.js') 
    446448        add_script(fakereq, 'common/js/search.js') 
     449        add_script(fakereq, '/jsi18n/' + str(req.locale)) 
    447450 
    448451        # Shortcut icon 
    449452        chrome['icon'] = self.get_icon_data(req) 
     
    685688        if content_type is None: 
    686689            content_type = 'text/html' 
    687690        method = {'text/html': 'xhtml', 
    688                   'text/plain': 'text'}.get(content_type, 'xml') 
     691                  'text/plain': 'text', 
     692                  'text/javascript': 'text'}.get(content_type, 'xml') 
    689693 
    690694        template = self.load_template(filename, method=method) 
    691695        data = self.populate_data(req, data) 
     
    785789            return stream 
    786790        return inner 
    787791 
     792 
     793class JSI18NModule(Component): 
     794 
     795    implements(IRequestHandler) 
     796 
     797    # IRequestHandler methods 
     798 
     799    def match_request(self, req): 
     800        match = re.match('/jsi18n/([^/]+)$', req.path_info) 
     801        if match: 
     802            req.args['locale'] = match.group(1) 
     803            return True 
     804 
     805    def process_request(self, req): 
     806        # FIXME: actually get the locale specified in the url 
     807        data = {'catalog': get_translations(), 
     808                'javascript_quote': javascript_quote} 
     809        # FIXME: Figure out which cache headers to set 
     810        return "jsi18ncatalog.js", data, 'text/javascript' 
     811 
  • trac/util/text.py

     
    6363        except UnicodeError: 
    6464            return unicode(text, locale.getpreferredencoding(), 'replace') 
    6565 
     66def javascript_quote(text): 
     67    return text.replace('\\', '\\\\').replace('\r', '\\r') \ 
     68               .replace('\n', '\\n').replace('\t', '\\t') \ 
     69               .replace("'", "\\'") 
     70 
    6671def unicode_quote(value, safe='/'): 
    6772    """A unicode aware version of urllib.quote""" 
    6873    return quote(value.encode('utf-8'), safe)