Page MenuHomePhabricator

Refactor react.i18n to allow functional usage
Open, LowPublic

Description

Thanks for wrapping Banana i18n lib as a React component!

There are cases when I would like to use the functionality of the Message but without any context, e.g. from inside the Redux state, but still be able to construct a React object tree and do all the current functionality like using React elements as placeholders.

This should be a tiny refactoring of the message.js that should also simplify testing -- essentially create a new exported function ( banana, messageKey, ...placeholders ) => {...} that can be used by itself, or continue using it via the <Message> element.

Thanks!

Event Timeline

Yurik updated the task description. (Show Details)

There are cases when I would like to use the functionality of the Message but without any context, e.g. from inside the Redux state, but still be able to construct a React object tree and do all the current functionality like using React elements as placeholders.

Can you describe this problem a little better? I'm not sure I understand what the value is in being able to use Message without any context. Are you passing around React components from within Redux?

Not exactly, even though this is also possible. There are cases in my app when i could be using multiple Banana contexts in the same place, e.g. showing text/links in different languages, and being able to call createMessage( banana, messageKey, ...placeholders ) with my own custom-configured banana instance would be very useful. Another case is that sometimes I need to override the way banana itself functions by overriding default implementation -- example is the well known MW qqx language code that allows MW to show debug messages instead of the real i18n resolution - for that I would also need to be able to provide custom banana handler. Thus, separating <Message> from the actual code that implements react substitutions would be highly useful to me.

Thx!

Not exactly, even though this is also possible. There are cases in my app when i could be using multiple Banana contexts in the same place, e.g. showing text/links in different languages

You can already do this by using multiple (even nested) contexts (sandbox):

const messages = {
  en: {
    hello: "Hello World!"
  },
  ja: {
    hello: "こんにちは世界!"
  }
};

export default function App() {
  return (
    <div className="App">
      <IntlProvider messages={messages} locale="en">
        <div>
          <Message id="hello" />
        </div>
        <IntlProvider messages={messages} locale="ja">
          <div>
            <Message id="hello" />
          </div>
        </IntlProvider>
      </IntlProvider>
    </div>
  );
}

and being able to call createMessage( banana, messageKey, ...placeholders ) with my own custom-configured banana instance would be very useful.

You could create a custom functional react component to do this (sandbox):

const messages = {
  en: {
    hello: "Hello World!"
  },
  ja: {
    hello: "こんにちは世界!"
  }
};

function BananaMessage({ banana, messageKey, placeholders }) {
  return (
    <BananaContext.Provider value={banana}>
      <Message id={messageKey} placeholders={placeholders} />
    </BananaContext.Provider>
  );
}

export default function App() {
  const banana = new Banana("en", {
    messages
  });

  const bananaJ = new Banana("ja", {
    messages
  });

  return (
    <div className="App">
      <div>
        <BananaMessage banana={banana} messageKey="hello" />
      </div>
      <div>
        <BananaMessage banana={bananaJ} messageKey="hello" />
      </div>
    </div>
  );
}

Another case is that sometimes I need to override the way banana itself functions by overriding default implementation -- example is the well known MW qqx language code that allows MW to show debug messages instead of the real i18n resolution - for that I would also need to be able to provide custom banana handler. Thus, separating <Message> from the actual code that implements react substitutions would be highly useful to me.

What would such a function return? Right now Message is just a function that returns a new React element. https://github.com/wikimedia/react.i18n/blob/a2085607c9648eb599c581b60933c95f5b84ed0e/src/message.js#L6-L7