forked from openedx/frontend-app-publisher
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "feat: move i18n to use edx package (openedx#33)" (openedx#34)
This reverts commit aca507d.
- Loading branch information
1 parent
aca507d
commit 9eb84c2
Showing
25 changed files
with
243 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
/** | ||
* For each locale we want to support, react-intl needs 1) the locale-data, which includes | ||
* information about how to format numbers, handle plurals, etc., and 2) the translations, as an | ||
* object holding message id / translated string pairs. A locale string and the messages object are | ||
* passed into the IntlProvider element that wraps your element hierarchy. | ||
* | ||
* Note that react-intl has no way of checking if the translations you give it actually have | ||
* anything to do with the locale you pass it; it will happily use whatever messages object you pass | ||
* in. However, if the locale data for the locale you passed into the IntlProvider was not | ||
* correctly installed with addLocaleData, all of your translations will fall back to the default | ||
* (in our case English), *even if you gave IntlProvider the correct messages object for that | ||
* locale*. | ||
*/ | ||
|
||
import { addLocaleData } from 'react-intl'; | ||
import Cookies from 'universal-cookie'; | ||
|
||
import arLocale from 'react-intl/locale-data/ar'; | ||
import enLocale from 'react-intl/locale-data/en'; | ||
import es419Locale from 'react-intl/locale-data/es'; | ||
import frLocale from 'react-intl/locale-data/fr'; | ||
import zhcnLocale from 'react-intl/locale-data/zh'; | ||
|
||
import COUNTRIES, { langs as countryLangs } from 'i18n-iso-countries'; | ||
import LANGUAGES, { langs as languageLangs } from '@cospired/i18n-iso-languages'; | ||
|
||
import arMessages from './messages/ar.json'; | ||
// no need to import en messages-- they are in the defaultMessage field | ||
import es419Messages from './messages/es_419.json'; | ||
import frMessages from './messages/fr.json'; | ||
import zhcnMessages from './messages/zh_CN.json'; | ||
|
||
addLocaleData([...arLocale, ...enLocale, ...es419Locale, ...frLocale, ...zhcnLocale]); | ||
|
||
// TODO: When we start dynamically loading translations only for the current locale, change this. | ||
COUNTRIES.registerLocale(require('i18n-iso-countries/langs/ar.json')); | ||
COUNTRIES.registerLocale(require('i18n-iso-countries/langs/en.json')); | ||
COUNTRIES.registerLocale(require('i18n-iso-countries/langs/es.json')); | ||
COUNTRIES.registerLocale(require('i18n-iso-countries/langs/fr.json')); | ||
COUNTRIES.registerLocale(require('i18n-iso-countries/langs/zh.json')); | ||
|
||
// TODO: When we start dynamically loading translations only for the current locale, change this. | ||
// TODO: Also note that Arabic (ar) and Chinese (zh) are missing here. That's because they're | ||
// not implemented in this library. If you read this and it's been a while, go check and see | ||
// if that's changed! | ||
LANGUAGES.registerLocale(require('@cospired/i18n-iso-languages/langs/en.json')); | ||
LANGUAGES.registerLocale(require('@cospired/i18n-iso-languages/langs/es.json')); | ||
LANGUAGES.registerLocale(require('@cospired/i18n-iso-languages/langs/fr.json')); | ||
|
||
const messages = { // current fallback strategy is to use the first two letters of the locale code | ||
ar: arMessages, | ||
es: es419Messages, | ||
fr: frMessages, | ||
zh: zhcnMessages, | ||
}; | ||
|
||
const cookies = new Cookies(); | ||
|
||
const getTwoLetterLanguageCode = code => code.substr(0, 2); | ||
|
||
// Get the locale by setting priority. Skip if we don't support that language. | ||
const getLocale = (localeStr) => { | ||
// 1. Explicit application request | ||
if (localeStr && messages[localeStr] !== undefined) { | ||
return localeStr; | ||
} | ||
// 2. User setting in cookie | ||
const cookieLangPref = cookies.get(process.env.LANGUAGE_PREFERENCE_COOKIE_NAME); | ||
if (cookieLangPref && messages[getTwoLetterLanguageCode(cookieLangPref)] !== undefined) { | ||
return getTwoLetterLanguageCode(cookieLangPref); | ||
} | ||
// 3. Browser language (default) | ||
return getTwoLetterLanguageCode(window.navigator.language); | ||
}; | ||
|
||
const getMessages = (locale = getLocale()) => messages[locale]; | ||
|
||
const rtlLocales = ['ar', 'he', 'fa', 'ur']; | ||
const isRtl = locale => rtlLocales.includes(locale); | ||
|
||
const handleRtl = () => { | ||
if (isRtl(getLocale())) { | ||
document.getElementsByTagName('html')[0].setAttribute('dir', 'rtl'); | ||
document.styleSheets[0].disabled = true; | ||
} else { | ||
document.styleSheets[1].disabled = true; | ||
} | ||
}; | ||
|
||
/** | ||
* Provides a lookup table of country IDs to country names for the current locale. | ||
*/ | ||
const getCountryMessages = (locale) => { | ||
const finalLocale = countryLangs().includes(locale) ? locale : 'en'; | ||
|
||
return COUNTRIES.getNames(finalLocale); | ||
}; | ||
|
||
/** | ||
* Provides a lookup table of language IDs to language names for the current locale. | ||
*/ | ||
const getLanguageMessages = (locale) => { | ||
const finalLocale = languageLangs().includes(locale) ? locale : 'en'; | ||
|
||
return LANGUAGES.getNames(finalLocale); | ||
}; | ||
|
||
const sortFunction = (a, b) => { | ||
// If localeCompare exists, use that. (Not supported in some older browsers) | ||
if (typeof String.prototype.localeCompare === 'function') { | ||
return a[1].localeCompare(b[1], getLocale()); | ||
} | ||
if (a[1] === b[1]) { | ||
return 0; | ||
} | ||
// Otherwise make a best effort. | ||
return a[1] > b[1] ? 1 : -1; | ||
}; | ||
|
||
/** | ||
* Provides a list of countries represented as objects of the following shape: | ||
* | ||
* { | ||
* key, // The ID of the country | ||
* name // The localized name of the country | ||
* } | ||
* | ||
* The list is sorted alphabetically in the current locale. | ||
* This is useful for select dropdowns primarily. | ||
*/ | ||
const getCountryList = (locale) => { | ||
const countryMessages = getCountryMessages(locale); | ||
return Object.entries(countryMessages) | ||
.sort(sortFunction) | ||
.map(([code, name]) => ({ code, name })); | ||
}; | ||
|
||
/** | ||
* Provides a list of languages represented as objects of the following shape: | ||
* | ||
* { | ||
* key, // The ID of the language | ||
* name // The localized name of the language | ||
* } | ||
* | ||
* The list is sorted alphabetically in the current locale. | ||
* This is useful for select dropdowns primarily. | ||
*/ | ||
const getLanguageList = (locale) => { | ||
const languageMessages = getLanguageMessages(locale); | ||
return Object.entries(languageMessages) | ||
.sort(sortFunction) | ||
.map(([code, name]) => ({ code, name })); | ||
}; | ||
|
||
export { | ||
getCountryList, | ||
getCountryMessages, | ||
getLanguageList, | ||
getLanguageMessages, | ||
getLocale, | ||
getMessages, | ||
handleRtl, | ||
isRtl, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,25 @@ | ||
import arMessages from './messages/ar.json'; | ||
import caMessages from './messages/ca.json'; | ||
// no need to import en messages-- they are in the defaultMessage field | ||
import es419Messages from './messages/es_419.json'; | ||
import frMessages from './messages/fr.json'; | ||
import zhcnMessages from './messages/zh_CN.json'; | ||
import heMessages from './messages/he.json'; | ||
import idMessages from './messages/id.json'; | ||
import kokrMessages from './messages/ko_kr.json'; | ||
import plMessages from './messages/pl.json'; | ||
import ptbrMessages from './messages/pt_br.json'; | ||
import ruMessages from './messages/ru.json'; | ||
import thMessages from './messages/th.json'; | ||
import ukMessages from './messages/uk.json'; | ||
import { intlShape } from 'react-intl'; | ||
import injectIntlWithShim from './injectIntlWithShim'; | ||
import { | ||
getCountryList, | ||
getCountryMessages, | ||
getLanguageList, | ||
getLanguageMessages, | ||
getLocale, | ||
getMessages, | ||
handleRtl, | ||
isRtl, | ||
} from './i18n-loader'; | ||
|
||
const messages = { | ||
ar: arMessages, | ||
'es-419': es419Messages, | ||
fr: frMessages, | ||
'zh-cn': zhcnMessages, | ||
ca: caMessages, | ||
he: heMessages, | ||
id: idMessages, | ||
'ko-kr': kokrMessages, | ||
pl: plMessages, | ||
'pt-br': ptbrMessages, | ||
ru: ruMessages, | ||
th: thMessages, | ||
uk: ukMessages, | ||
export { | ||
injectIntlWithShim as injectIntl, | ||
getCountryList, | ||
getCountryMessages, | ||
getLanguageList, | ||
getLanguageMessages, | ||
getLocale, | ||
getMessages, | ||
handleRtl, | ||
isRtl, | ||
intlShape, | ||
}; | ||
|
||
export default messages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React from 'react'; | ||
import { injectIntl, intlShape } from 'react-intl'; | ||
import { logError } from '@edx/frontend-logging'; | ||
|
||
|
||
const injectIntlWithShim = (WrappedComponent) => { | ||
class ShimmedIntlComponent extends React.Component { | ||
static propTypes = { | ||
intl: intlShape.isRequired, | ||
}; | ||
|
||
constructor(props) { | ||
super(props); | ||
this.shimmedIntl = Object.create(this.props.intl, { | ||
formatMessage: { | ||
value: (definition) => { | ||
if (definition === undefined || definition.id === undefined) { | ||
const error = new Error('i18n error: An undefined message was supplied to intl.formatMessage.'); | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.error(error); // eslint-disable-line no-console | ||
return '!!! Missing message supplied to intl.formatMessage !!!'; | ||
} | ||
logError(error); | ||
return ''; // Fail silent in production | ||
} | ||
return this.props.intl.formatMessage(definition); | ||
}, | ||
}, | ||
}); | ||
} | ||
|
||
render() { | ||
return <WrappedComponent {...this.props} intl={this.shimmedIntl} />; | ||
} | ||
} | ||
|
||
return injectIntl(ShimmedIntlComponent); | ||
}; | ||
|
||
|
||
export default injectIntlWithShim; |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.