/
jquery.gettext.js
144 lines (132 loc) · 4.64 KB
/
jquery.gettext.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* gettext for jQuery
*
* Copyright (c) 2008 Sabin Iacob (m0n5t3r) <iacobs@m0n5t3r.info>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* @license http://www.gnu.org/licenses/gpl.html
* @project jquery.gettext
*
* Usage:
*
* This plugin expects its input data to be a JSON object like
* {"": header, "string": "translation", ...}
*
* After getting the server side set up (either as a static file - my choice - or
* as a web service), the client side is simple:
* * add to the head section of the page something like
* <link href="path/to/translation.json" lang="ro" rel="gettext"/>
* * in your script, use $.gt.gettext(string) or _(string); for plural forms, use
* $.gt.ngettext(sg, pl1[, pl2, ...], count) or n_(sg, pl1[, pl2, ...], count)
* * to extract strings to a .po file, you can use standard gettext utilities like
* xgettext and msgfmt; to generate the JSON, one could use the following Python
* snippet, assuming a domain.mo file exists under path/lang/LC_MESSAGES:
*
* import simplejson as enc
*
* def gettext_json(domain, path, lang = [], indent = False):
* try:
* tr = gettext.translation(domain, path, lang)
* return enc.dumps(tr._catalog, ensure_ascii = False, indent = indent)
* except IOError:
* return None
*
* why go through the additional hassle of gettext? well, it's a matter of
* preference, the main advantags I see are:
* * well known editing tools like KBabel, poEdit, gtranslator, Emacs PO mode,
* etc.
* * translation memory, fuzzy matches and other features that get really
* helpful when your application is big and you have hundreds of strings
*/
(function($) {
$.gt = $.gt || {};
$.extend($.gt, {
messages: {},
lang: 'C',
setLang: function(code) { $.gt.lang = typeof code == 'string' && code != ' ' ? code : 'C'; },
pl_re: /^Plural-Forms:\s*nplurals\s*=\s*(\d+);\s*plural\s*=\s*([^a-zA-Z0-9\$]*([a-zA-Z0-9\$]+).+)$/m,
plural: function(n) {return n != 1;},
load: function() {
$('link[rel=gettext]').each(function(){
var lang = this.lang;
$.get(this.href, function(data){
$.gt.messages[lang] = $.gt.messages[lang] || {};
try {
var messages = eval('(' + data + ')');
} catch(e) {
return;
}
$.extend($.gt.messages[lang], messages);
var pl = $.gt.pl_re.exec($.gt.messages[lang]['']);
if(pl){
var expr = pl[2];
var np = pl[1];
var v = pl[3];
try {
var fn = eval('(function(' + v + ') {return ' + expr + ';})');
} catch(e) {
return;
}
$.gt.plural = fn;
}
});
});
$.gt.setLang($('html').attr('lang'));
},
gettext: function(msgstr) {
var lang = $.gt.lang;
if(lang == 'C' || typeof $.gt.messages[lang] == 'undefined') {
return msgstr;
}
var trans = $.gt.messages[lang][msgstr];
if(typeof trans == 'string') { // regular action
return trans;
} else if(typeof trans == 'object' && trans.constructor == Array) { // the translation contains plural(s), yet gettext was called
return trans[0];
}
return msgstr;
},
ngettext: function() {
var lang = $.gt.lang;
var argv = Array.apply(null, arguments);
var cnt = argv[argv.length - 1];
var sg = argv[0];
var pls = argv.slice(0, -1);
var trans = pls;
if(lang != 'C' && typeof $.gt.messages[lang] != 'undefined') {
trans = $.gt.messages[lang][sg];
}
if(typeof trans == 'string') { // called ngettext, but no plural forms available :-?
return trans;
} else if(typeof trans == 'object' && trans.constructor == Array) {
var pl = $.gt.plural(cnt);
if(typeof pl == 'boolean' && pls.length == 2) {
pl = pl ? 1 : 0;
}
if(typeof pl == 'number' && pl < trans.length) {
return trans[pl];
}
}
return sg;
}
});
// The following initialisation method has been taken ou of the "ready" event
// to prevent problems with the loading sequence. Just make sure the gettext plugin
// is called before other scripts who need localization
//$('document').ready($.gt.load);
$.gt.load();
})(jQuery);
if(typeof _ == 'undefined') {
var _ = jQuery.gt.gettext;
}
if(typeof n_ == 'undefined') {
var n_ = jQuery.gt.ngettext;
}