@@ -52,10 +52,22 @@ export type InitializeOptions = {
52
52
ignoreTranslateChildren ?: boolean
53
53
} ;
54
54
55
+ // This is to get around the whole default options issue with Flow
56
+ // I tried using the $Diff approach, but with no luck so for now stuck with this terd.
57
+ // Because sometimes you just want flow to shut up!
58
+ type InitializeOptionsRequired = {
59
+ renderToStaticMarkup : renderToStaticMarkupFunction | false ,
60
+ renderInnerHtml : boolean ,
61
+ onMissingTranslation : onMissingTranslationFunction ,
62
+ defaultLanguage : string ,
63
+ ignoreTranslateChildren : boolean
64
+ } ;
65
+
55
66
export type TranslateOptions = {
56
67
language ?: string ,
57
68
renderInnerHtml ?: boolean ,
58
69
onMissingTranslation ?: onMissingTranslationFunction ,
70
+ defaultLanguage ?: string ,
59
71
ignoreTranslateChildren ?: boolean
60
72
} ;
61
73
@@ -66,7 +78,7 @@ export type AddTranslationOptions = {
66
78
export type LocalizeState = {
67
79
+ languages : Language [ ] ,
68
80
+ translations : Translations ,
69
- + options : InitializeOptions
81
+ + options : InitializeOptionsRequired
70
82
} ;
71
83
72
84
export type TranslatedLanguage = {
@@ -102,7 +114,7 @@ export type MultipleLanguageTranslation = {
102
114
type MissingTranslationOptions = {
103
115
translationId : string ,
104
116
languageCode : string ,
105
- defaultTranslation : string
117
+ defaultTranslation : LocalizedElement
106
118
} ;
107
119
108
120
export type onMissingTranslationFunction = (
@@ -274,9 +286,9 @@ export function translations(
274
286
}
275
287
276
288
export function options (
277
- state : InitializeOptions = defaultTranslateOptions ,
289
+ state : InitializeOptionsRequired = defaultTranslateOptions ,
278
290
action : ActionDetailed
279
- ) : InitializeOptions {
291
+ ) : InitializeOptionsRequired {
280
292
switch ( action . type ) {
281
293
case INITIALIZE :
282
294
const options : any = action . payload . options || { } ;
@@ -288,10 +300,11 @@ export function options(
288
300
}
289
301
}
290
302
291
- export const defaultTranslateOptions : InitializeOptions = {
303
+ export const defaultTranslateOptions : InitializeOptionsRequired = {
292
304
renderToStaticMarkup : false ,
293
305
renderInnerHtml : false ,
294
306
ignoreTranslateChildren : false ,
307
+ defaultLanguage : '' ,
295
308
onMissingTranslation : ( { translationId, languageCode } ) =>
296
309
'Missing translationId: ${ translationId } for language: ${ languageCode }'
297
310
} ;
@@ -361,8 +374,20 @@ export const getTranslations = (state: LocalizeState): Translations => {
361
374
export const getLanguages = ( state : LocalizeState ) : Language [ ] =>
362
375
state . languages ;
363
376
364
- export const getOptions = ( state : LocalizeState ) : InitializeOptions =>
365
- state . options ;
377
+ export const getOptions = ( state : LocalizeState ) : InitializeOptionsRequired => {
378
+ const options = Object . assign ( { } , state . options ) ;
379
+ let languages ;
380
+
381
+ // If there isn't a default language, grab the first languages from the
382
+ // available languages as default
383
+
384
+ if ( ! options . defaultLanguage ) {
385
+ languages = getLanguages ( state ) || [ ] ;
386
+ options . defaultLanguage = languages [ 0 ] ? languages [ 0 ] . code : '' ;
387
+ }
388
+
389
+ return options ;
390
+ } ;
366
391
367
392
export const getActiveLanguage = ( state : LocalizeState ) : Language => {
368
393
const languages = getLanguages ( state ) ;
@@ -452,43 +477,60 @@ export const getTranslate: Selector<
452
477
: translationsForActiveLanguage ;
453
478
454
479
const defaultTranslations =
455
- activeLanguage &&
456
- activeLanguage . code === initializeOptions . defaultLanguage
480
+ activeLanguage && activeLanguage . code === defaultLanguage
457
481
? translationsForActiveLanguage
458
- : initializeOptions . defaultLanguage !== undefined
459
- ? getTranslationsForLanguage ( initializeOptions . defaultLanguage )
460
- : { } ;
482
+ : getTranslationsForLanguage ( defaultLanguage ) ;
461
483
462
484
const languageCode =
463
485
overrideLanguage !== undefined
464
486
? overrideLanguage
465
487
: activeLanguage && activeLanguage . code ;
466
488
467
- const onMissingTranslation = ( translationId : string ) => {
468
- return mergedOptions . onMissingTranslation ( {
469
- translationId,
489
+ const mergedOptions = { ...defaultOptions , ...translateOptions } ;
490
+
491
+ const getTranslation = ( translationId : string ) => {
492
+ const hasValidTranslation = translations [ translationId ] !== undefined ;
493
+ const hasValidDefaultTranslation =
494
+ defaultTranslations [ translationId ] !== undefined ;
495
+
496
+ const defaultTranslation = hasValidDefaultTranslation
497
+ ? getLocalizedElement ( {
498
+ translation : defaultTranslations [ translationId ] ,
499
+ data,
500
+ renderInnerHtml : mergedOptions . renderInnerHtml
501
+ } )
502
+ : "No default translation found! Ensure you've added translations for your default langauge." ;
503
+
504
+ // if translation is not valid then generate the on missing translation message in it's place
505
+ const translation = hasValidTranslation
506
+ ? translations [ translationId ]
507
+ : mergedOptions . onMissingTranslation ( {
508
+ translationId,
509
+ languageCode,
510
+ defaultTranslation
511
+ } ) ;
512
+
513
+ // if translations are missing than ovrride data to include translationId, languageCode
514
+ // as these will be needed to render missing translations message
515
+ const translationData = hasValidTranslation
516
+ ? data
517
+ : { translationId, languageCode } ;
518
+
519
+ return getLocalizedElement ( {
520
+ translation,
521
+ data : translationData ,
470
522
languageCode,
471
- defaultTranslation : defaultTranslations [ translationId ]
523
+ renderInnerHtml : mergedOptions . renderInnerHtml
472
524
} ) ;
473
525
} ;
474
526
475
- const mergedOptions = { ...defaultOptions , ...translateOptions } ;
476
- const { renderInnerHtml } = mergedOptions ;
477
- const sharedParams = {
478
- translations,
479
- data,
480
- languageCode,
481
- renderInnerHtml,
482
- onMissingTranslation
483
- } ;
484
-
485
527
if ( typeof value === 'string' ) {
486
- return getLocalizedElement ( { translationId : value , ... sharedParams } ) ;
528
+ return getTranslation ( value ) ;
487
529
} else if ( Array . isArray ( value ) ) {
488
530
return value . reduce ( ( prev , cur ) => {
489
531
return {
490
532
...prev ,
491
- [ cur ] : getLocalizedElement ( { translationId : cur , ... sharedParams } )
533
+ [ cur ] : getTranslation ( cur )
492
534
} ;
493
535
} , { } ) ;
494
536
} else {
0 commit comments