Skip to content

Commit 8e8e286

Browse files
committed
Merge branch 'decouple-translate' of git://github.com/janlazo/vue-gettext into janlazo-decouple-translate
2 parents e2fb7c4 + 9ee01eb commit 8e8e286

File tree

4 files changed

+204
-4
lines changed

4 files changed

+204
-4
lines changed

build/rollup.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module.exports = {
1818
format: 'umd',
1919
globals,
2020
name: 'VueGettext',
21+
exports: 'named',
2122
},
2223
external: Object.keys(globals),
2324
plugins: [

src/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ let GetTextPlugin = function (Vue, options = {}) {
5252

5353
Config(Vue, languageVm, options.silent, options.autoAddKeyAttributes, options.muteLanguages)
5454

55+
translate.initTranslations(options.translations, Vue.config)
56+
5557
// Makes <translate> available as a global component.
5658
Vue.component('translate', Component)
5759

@@ -70,3 +72,4 @@ let GetTextPlugin = function (Vue, options = {}) {
7072
}
7173

7274
export default GetTextPlugin
75+
export {translate}

src/translate.js

+27-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import plurals from './plurals'
2-
import { _Vue } from './localVue'
32

43
const SPACING_RE = /\s{2,}/g
4+
// Default configuration if only the translation is passed.
5+
let _config = {
6+
language: '',
7+
getTextPluginSilent: false,
8+
getTextPluginMuteLanguages: [],
9+
silent: false,
10+
}
11+
let _translations = {}
512

613
export default {
714

@@ -16,13 +23,13 @@ export default {
1623
*
1724
* @return {String} The translated string
1825
*/
19-
getTranslation: function (msgid, n = 1, context = null, defaultPlural = null, language = _Vue.config.language) {
26+
getTranslation: function (msgid, n = 1, context = null, defaultPlural = null, language = _config.language) {
2027

2128
if (!msgid) {
2229
return '' // Allow empty strings.
2330
}
2431

25-
let silent = _Vue.config.getTextPluginSilent || (_Vue.config.getTextPluginMuteLanguages.indexOf(language) !== -1)
32+
let silent = _config.getTextPluginSilent || (_config.getTextPluginMuteLanguages.indexOf(language) !== -1)
2633

2734
// Default untranslated string, singular or plural.
2835
let untranslated = defaultPlural && plurals.getTranslationIndex(language, n) > 0 ? defaultPlural : msgid
@@ -33,7 +40,7 @@ export default {
3340
// See the `Language` section in https://www.gnu.org/software/gettext/manual/html_node/Header-Entry.html
3441
// So try `ll_CC` first, or the `ll` abbreviation which can be three-letter sometimes:
3542
// https://www.gnu.org/software/gettext/manual/html_node/Language-Codes.html#Language-Codes
36-
let translations = _Vue.$translations[language] || _Vue.$translations[language.split('_')[0]]
43+
let translations = _translations[language] || _translations[language.split('_')[0]]
3744

3845
if (!translations) {
3946
if (!silent) {
@@ -157,4 +164,20 @@ export default {
157164
return this.getTranslation(msgid, n, context, plural)
158165
},
159166

167+
/*
168+
* Initialize local state for translations and configuration
169+
* so that it works without Vue.
170+
*
171+
* @param {Object} translations - translations.json
172+
* @param {Object} config - Vue.config
173+
*
174+
*/
175+
initTranslations: function (translations, config) {
176+
if (translations && typeof translations === 'object') {
177+
_translations = translations
178+
}
179+
if (config && typeof config === 'object') {
180+
_config = config
181+
}
182+
},
160183
}

test/specs/translate.spec.js

+173
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,176 @@ describe('Translate tests', () => {
179179
})
180180

181181
})
182+
183+
describe('Translate tests without Vue', () => {
184+
let config
185+
186+
beforeEach(function () {
187+
config = {
188+
language: 'en_US',
189+
getTextPluginSilent: false,
190+
getTextPluginMuteLanguages: [],
191+
silent: false,
192+
}
193+
translate.initTranslations(translations, config)
194+
})
195+
196+
let translated
197+
198+
it('tests the getTranslation() method', () => {
199+
200+
translated = translate.getTranslation('', 1, null, 'fr_FR')
201+
expect(translated).to.equal('')
202+
203+
translated = translate.getTranslation('Unexisting language', null, null, null, 'be_FR')
204+
expect(translated).to.equal('Unexisting language')
205+
206+
translated = translate.getTranslation('Untranslated key', null, null, null, 'fr_FR')
207+
expect(translated).to.equal('Untranslated key')
208+
209+
translated = translate.getTranslation('Pending', 1, null, null, 'fr_FR')
210+
expect(translated).to.equal('En cours')
211+
212+
translated = translate.getTranslation('%{ carCount } car', 2, null, null, 'fr_FR')
213+
expect(translated).to.equal('%{ carCount } véhicules')
214+
215+
translated = translate.getTranslation('Answer', 1, 'Verb', null, 'fr_FR')
216+
expect(translated).to.equal('Réponse (verbe)')
217+
218+
translated = translate.getTranslation('Answer', 1, 'Noun', null, 'fr_FR')
219+
expect(translated).to.equal('Réponse (nom)')
220+
221+
translated = translate.getTranslation('Pending', 1, null, null, 'en_US')
222+
expect(translated).to.equal('Pending')
223+
224+
// If no translation exists, display the default singular form (if n < 2).
225+
translated = translate.getTranslation('Untranslated %{ n } item', 0, null, 'Untranslated %{ n } items', 'fr_FR')
226+
expect(translated).to.equal('Untranslated %{ n } item')
227+
228+
// If no translation exists, display the default plural form (if n > 1).
229+
translated = translate.getTranslation('Untranslated %{ n } item', 10, null, 'Untranslated %{ n } items', 'fr_FR')
230+
expect(translated).to.equal('Untranslated %{ n } items')
231+
232+
// Test that it works when a msgid exists with and without a context, see #32.
233+
translated = translate.getTranslation('Object', null, null, null, 'fr_FR')
234+
expect(translated).to.equal('Objet')
235+
translated = translate.getTranslation('Object', null, 'Context', null, 'fr_FR')
236+
expect(translated).to.equal('Objet avec contexte')
237+
238+
// Ensure that pluralization is right in English when there are no English translations.
239+
translated = translate.getTranslation('Untranslated %{ n } item', 0, null, 'Untranslated %{ n } items', 'en_US')
240+
expect(translated).to.equal('Untranslated %{ n } items')
241+
translated = translate.getTranslation('Untranslated %{ n } item', 1, null, 'Untranslated %{ n } items', 'en_US')
242+
expect(translated).to.equal('Untranslated %{ n } item')
243+
translated = translate.getTranslation('Untranslated %{ n } item', 2, null, 'Untranslated %{ n } items', 'en_US')
244+
expect(translated).to.equal('Untranslated %{ n } items')
245+
246+
// Test plural message with multiple contexts (default context and 'Context'')
247+
translated = translate.getTranslation('%{ carCount } car (multiple contexts)', 1, null, null, 'en_US')
248+
expect(translated).to.equal('1 car')
249+
translated = translate.getTranslation('%{ carCount } car (multiple contexts)', 2, null, null, 'en_US')
250+
expect(translated).to.equal('%{ carCount } cars')
251+
translated = translate.getTranslation('%{ carCount } car (multiple contexts)', 1, 'Context', null, 'en_US')
252+
expect(translated).to.equal('1 car with context')
253+
translated = translate.getTranslation('%{ carCount } car (multiple contexts)', 2, 'Context', null, 'en_US')
254+
expect(translated).to.equal('%{ carCount } cars with context')
255+
256+
})
257+
258+
it('tests the gettext() method', () => {
259+
260+
let undetectableGettext = translate.gettext.bind(translate) // Hide from gettext-extract.
261+
262+
config.language = 'fr_FR'
263+
expect(undetectableGettext('Pending')).to.equal('En cours')
264+
265+
config.language = 'en_US'
266+
expect(undetectableGettext('Pending')).to.equal('Pending')
267+
268+
})
269+
270+
it('tests the pgettext() method', () => {
271+
272+
let undetectablePgettext = translate.pgettext.bind(translate) // Hide from gettext-extract.
273+
274+
config.language = 'fr_FR'
275+
expect(undetectablePgettext('Noun', 'Answer')).to.equal('Réponse (nom)')
276+
277+
config.language = 'en_US'
278+
expect(undetectablePgettext('Noun', 'Answer')).to.equal('Answer (noun)')
279+
280+
})
281+
282+
it('tests the ngettext() method', () => {
283+
284+
let undetectableNgettext = translate.ngettext.bind(translate) // Hide from gettext-extract.
285+
286+
config.language = 'fr_FR'
287+
expect(undetectableNgettext('%{ carCount } car', '%{ carCount } cars', 2)).to.equal('%{ carCount } véhicules')
288+
289+
config.language = 'en_US'
290+
expect(undetectableNgettext('%{ carCount } car', '%{ carCount } cars', 2)).to.equal('%{ carCount } cars')
291+
292+
// If no translation exists, display the default singular form (if n < 2).
293+
config.language = 'fr_FR'
294+
expect(undetectableNgettext('Untranslated %{ n } item', 'Untranslated %{ n } items', -1))
295+
.to.equal('Untranslated %{ n } item')
296+
297+
// If no translation exists, display the default plural form (if n > 1).
298+
config.language = 'fr_FR'
299+
expect(undetectableNgettext('Untranslated %{ n } item', 'Untranslated %{ n } items', 2))
300+
.to.equal('Untranslated %{ n } items')
301+
302+
})
303+
304+
it('tests the npgettext() method', () => {
305+
306+
let undetectableNpgettext = translate.npgettext.bind(translate) // Hide from gettext-extract
307+
308+
config.language = 'fr_FR'
309+
expect(undetectableNpgettext('Noun', '%{ carCount } car (noun)', '%{ carCount } cars (noun)', 2))
310+
.to.equal('%{ carCount } véhicules (nom)')
311+
312+
config.language = 'en_US'
313+
expect(undetectableNpgettext('Verb', '%{ carCount } car (verb)', '%{ carCount } cars (verb)', 2))
314+
.to.equal('%{ carCount } cars (verb)')
315+
316+
config.language = 'fr_FR'
317+
expect(undetectableNpgettext('Noun', '%{ carCount } car (noun)', '%{ carCount } cars (noun)', 1))
318+
.to.equal('%{ carCount } véhicule (nom)')
319+
320+
config.language = 'en_US'
321+
expect(undetectableNpgettext('Verb', '%{ carCount } car (verb)', '%{ carCount } cars (verb)', 1))
322+
.to.equal('%{ carCount } car (verb)')
323+
324+
// If no translation exists, display the default singular form (if n < 2).
325+
config.language = 'fr_FR'
326+
expect(undetectableNpgettext('Noun', 'Untranslated %{ n } item (noun)', 'Untranslated %{ n } items (noun)', 1))
327+
.to.equal('Untranslated %{ n } item (noun)')
328+
329+
// If no translation exists, display the default plural form (if n > 1).
330+
config.language = 'fr_FR'
331+
expect(undetectableNpgettext('Noun', 'Untranslated %{ n } item (noun)', 'Untranslated %{ n } items (noun)', 2))
332+
.to.equal('Untranslated %{ n } items (noun)')
333+
334+
})
335+
336+
it('works when a msgid exists with and without a context, but the one with the context has not been translated', () => {
337+
338+
expect(config.silent).to.equal(false)
339+
console.warn = sinon.spy(console, 'warn')
340+
341+
translated = translate.getTranslation('May', null, null, null, 'fr_FR')
342+
expect(translated).to.equal('Pourrait')
343+
344+
translated = translate.getTranslation('May', null, 'Month name', null, 'fr_FR')
345+
expect(translated).to.equal('May')
346+
347+
expect(console.warn).calledOnce
348+
expect(console.warn).calledWith('Untranslated fr_FR key found: May (with context: Month name)')
349+
350+
console.warn.restore()
351+
352+
})
353+
354+
})

0 commit comments

Comments
 (0)