Skip to content

Instantly share code, notes, and snippets.

@f0urfingeredfish
Created January 26, 2018 20:50
Show Gist options
  • Save f0urfingeredfish/44a3c12b95caf157ad06839ba4b98524 to your computer and use it in GitHub Desktop.
Save f0urfingeredfish/44a3c12b95caf157ad06839ba4b98524 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react'
import PropTypes from 'prop-types'
export const templateConcat = (strings, expressions) =>
strings.reduce((prevValue, currentValue, index) => {
const expressionValue = expressions[index]
if (expressionValue) {
return `${prevValue}${currentValue}${expressionValue}`
}
return `${prevValue}${currentValue}`
}, '')
class Localized extends Component {
constructor(props) {
super(props)
this.translate = this.translate.bind(this)
this.onLangChange = this.onLangChange.bind(this)
this.state = {
translation: templateConcat(this.props.strings, this.props.expressions),
}
}
componentWillMount() {
if (window.Localize) {
window.Localize.on('setLanguage', this.onLangChange)
this.translate()
}
}
componentWillUnmount() {
if (window.Localize) {
window.Localize.off('setLanguage', this.onLangChange)
}
}
onLangChange({ to = 'en' }) {
// this event happens when Localize has loaded and when languages are changed via the picker
if (to === 'en') {
// Don't translate if locale is set to english assuming English is what you write your site in
this.setState({
translation: templateConcat(this.props.strings, this.props.expressions),
})
} else {
this.translate()
}
}
translate() {
if (window.Localize && window.Localize.loaded) {
this.setState({
translation: templateConcat(
this.props.strings.map(value => window.Localize.translate(value)),
this.props.translateExpressions
? this.props.expressions.map(value => window.Localize.translate(value))
: this.props.expressions
),
})
}
}
render() {
return this.state.translation
}
}
Localized.defaultProps = {
translateExpressions: false,
strings: [],
expressions: [],
}
Localized.propTypes = {
expressions: PropTypes.arrayOf(PropTypes.string).isRequired,
strings: PropTypes.arrayOf(PropTypes.string).isRequired,
translateExpressions: PropTypes.bool,
}
/**
* A Tagged template literal that will translate all strings but NOT expressions
* @example localize`This string will get translated ${thisWont}`
* @param {TemplateLiteral}
* @returns {Component || String} A <Localized> component or an English string
*/
export const localize = (strings, ...expressions) => {
if (!window.Localize) {
return templateConcat(strings, expressions)
}
return <Localized strings={strings} expressions={expressions} />
}
/**
* A Tagged template literal that will translate all strings and expressions
* @example localizeAll`This string will get translated ${thisExpressionWillGetTranslatedToo}`
* @param {TemplateLiteral}
* @returns {Component || String} A <Localized> component or an English string
*/
export const localizeAll = (strings, ...expressions) => {
if (!window.Localize) {
return templateConcat(strings, expressions)
}
return <Localized strings={strings} expressions={expressions} translateExpressions />
}
export default localize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment