GithubHelp home page GithubHelp logo

Comments (12)

fvicente avatar fvicente commented on June 13, 2024 16

I came up with a helper component that does the 'rich text interpolation'. It's written in ES5, and without semi-colon (airbnb rules).

import React from 'react'
import PropTypes from 'prop-types'
import { Text } from 'react-native'
import I18n from 'react-native-i18n'

export const RichI18n = (props) => {
  const { id, values, baseComponent, baseComponentStyle, baseComponentProps, ...other } = props
  // get the translations interpoling the placeholder by itself
  const keys = Object.keys(values)
  const placeHolders = {}
  keys.forEach((key) => placeHolders[key] = `{{${key}}}`)
  const translation = I18n.t(id, { ...(other || {}), ...placeHolders }) || ''
  // split the translated string, using default i18n-js regex, odd indexes will correlate to a key to be interpolated
  // https://github.com/fnando/i18n-js/blob/master/app/assets/javascripts/i18n.js
  const splitted = translation.split(/(?:\{\{|%\{)(.*?)(?:\}\}?)/gm)
  const interpolated = []
  splitted.forEach((str, idx) => {
    if ((idx % 2) === 0) {
      interpolated.push(str)
    } else {
      const child = values[str]
      if (typeof child === 'string') {
        interpolated.push(child)
      } else {
        interpolated.push(React.cloneElement(child, { key: idx }))
      }
    }
  })
  const BaseComponent = baseComponent
  return (
    <BaseComponent style={baseComponentStyle} {...baseComponentProps}>{interpolated}</BaseComponent>
  )
}

RichI18n.propTypes = {
  id: PropTypes.string.isRequired,
  values: PropTypes.object,
  baseComponent: PropTypes.any,
  baseComponentStyle: PropTypes.object,
  baseComponentProps: PropTypes.object
}

RichI18n.defaultProps = {
  values: {},
  baseComponent: Text,
  baseComponentStyle: {},
  baseComponentProps: {}
}

Usage:

 <RichI18n
  id="my.interpolation.test"
  defaultValue="This is an {{interpolation}} test {{plain}} where {{you}} can repeat {{interpolation}} variables {{translated}}"
  values={{
    interpolation: <Text style={{ fontWeight: 'bold' }}>bold</Text>,
    you: <Text style={{ color: 'red' }}>me</Text>,
    plain: 'Just plain text',
    translated: I18n.t('Translated text', { defaultValue: 'Translated text' })
  }}
/>

from react-native-i18n.

TONYHOKAN avatar TONYHOKAN commented on June 13, 2024 6

i am facing same issue and just make a quick solution:
create a function that return array of react components

const tWithComponent = (i18nKey, components, t) => {
      let string = t(i18nKey)
      let results = []
      components.forEach((component, idx) => {
        let splitedStrings = string.split('{' + idx + '}')
        results.push(splitedStrings[0])
        results.push(component)
        string = splitedStrings[1]
      })
      results.push(string)
      return results
    }
return (
...
{tWithComponent('doNotHaveAccountYet', [<Link key='0' to='/signup'>{t('signUp')}</Link>], t)}
...
)

i18n string will look like:

"doNotHaveAccountYet": "Do not have account yet? Click {0} to start!"

from react-native-i18n.

ruskid avatar ruskid commented on June 13, 2024 4

Sure. basically I have some text needed for translation "By using Application you accept the privacy politics and our terms of use." where privacy politics is the link or text with different styles.

I want to avoid splitting the text into multiple parts:

  • By using Application you accept the
  • privacy politics
  • and
  • terms of use

I want to translate the whole phrase like this
'login_condition': 'By using %{appName} you accept the %{privacyLink} and our %{termLink}',

and can't find the way to do it.

from react-native-i18n.

mmazzarolo avatar mmazzarolo commented on June 13, 2024

I'm sorry but I'm not able to understand what you are trying to achieve, can you provide some more info?
Values interpolation should work exactly like in i18n-js.

from react-native-i18n.

mmazzarolo avatar mmazzarolo commented on June 13, 2024

Correct me if I am mistaken but you're trying to interpolate React Component (not simple object/text) because you need to style a portion of text, am I right?
Unfortunately this is out of the scope of this library.
Basically you can interpolate text in this way:

// Translation definition:
WELCOME_MSG: 'Hello {{name}}!'

// In you component:
I18n.t('WELCOME_MSG', { name: 'Alexander' })

But you can't style Alexander differently from the rest of the text, you must create your own function/wrapper to do so... 🙍

from react-native-i18n.

mmazzarolo avatar mmazzarolo commented on June 13, 2024

Closing, let me know if you find any cool solution to your issue!

from react-native-i18n.

ismdcf avatar ismdcf commented on June 13, 2024

@mmazzarolo can you guide in writing the wrapper

from react-native-i18n.

compojoom avatar compojoom commented on June 13, 2024

@TONYHOKAN - what is t?

from react-native-i18n.

TONYHOKAN avatar TONYHOKAN commented on June 13, 2024

@compojoom
i am using react-i18next and t is the function passed by I18n component to child function and triggers loading the translation files needed. I think the t is equal to I18n.t().

from react-native-i18n.

compojoom avatar compojoom commented on June 13, 2024

@TONYHOKAN thanks! Why are you passing t as parameter to the function?
I rewrote it to:

export const tWithComponent = (i18nKey, components) => {
  let string = I18n.t(i18nKey)
  let results = []
  components.forEach((component, idx) => {
    let splitedStrings = string.split('{' + idx + '}')
    results.push(splitedStrings[0])
    results.push(component)
    string = splitedStrings[1]
  })
  results.push(string)
  return results
}

and it works! Thanks again :)

from react-native-i18n.

TONYHOKAN avatar TONYHOKAN commented on June 13, 2024

@compojoom as i was using react-i18next HOC to wrap the parent component of tWithComponent and could not directly access t via global context. Your are right that we do not no need to pass t as parameter if you can access t function in global context.

from react-native-i18n.

vpolian-kw avatar vpolian-kw commented on June 13, 2024
// T.js
import React from 'react';
import i18n from 'i18n-js';

export function T({ id, values, components = [] }) {
  const message = i18n.t(id, values);
  const row = React.useMemo(() =>
  {
    const nodes = [];
    let messageToParse = message;
    components.forEach(({ component: Component, props }, index) =>
    {
      const componentRegExp = new RegExp(`<${index}>(.*)</${index}>`, 'gi');
      const [beforeText, componentText, restText] = messageToParse.split(componentRegExp);
      messageToParse = restText;
      nodes.push(
        <Text id={beforeText}>{beforeText}</Text>,
        <Component key={index} {...props}>
          {componentText}
        </Component>,
      );
    });
    nodes.push(<Text id={messageToParse}>{messageToParse}</Text>);
    return nodes;
  }, [message, components]);
  return <>{row}</>;
}

Usage:

{"example.message": "This is {{exampleText}} with <0>Link 1</0> and <1>Link 2</1>."}
const components = [
  {
    component: Text,
    props: {
      style: styles.links,
      onPress: openLink1,
    },
  },
  {
    component: Text,
    props: {
      style: styles.links,
      onPress: openLink2,
    },
  },
]

<T
  id="example.message"
  values={{ exampleText: "example message" }}
  components={components}
/>

from react-native-i18n.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.