Skip to content
This repository has been archived by the owner on Nov 15, 2019. It is now read-only.

I18N for HTML fragments #46

Open
aikar opened this issue Apr 15, 2017 · 5 comments
Open

I18N for HTML fragments #46

aikar opened this issue Apr 15, 2017 · 5 comments

Comments

@aikar
Copy link

aikar commented Apr 15, 2017

per #26
It's almost guaranteed anyone doing a serious I18N roll out will run into a scenario like this:

Hello {user}, Please <a href={dial}>call</a> or <a href={mailto}>email</a> us for support

This plugin currently offers no native way to create this as a single i18n string for translation.

Breaking it up into

Hello
Please
call
or
email
us for support

Is not a valid solution as the order of the words are likely to change in other languages.
This needs to be handled as a single string.

In React, I created a work around seen here: #26 (comment)

But this required us to use the dangerous inner html of React and uglifies the code writing HTML inside of strings.

We need a solution for this problem so that this plugin can be a complete i18n solution (along with #6)

Proposal:
JS comment tags?
JSX example


const str = 
/* @i18n */
<span>Hello {user}, Please <a href={dial}>call</a> or <a href={mailto}>email</a> us for support</span>
/* @i18n:start */;

Or maybe support:

__(<span>Hello {user}, Please <a href={dial}>call</a> or <a href={mailto}>email</a> us for support</span>)

Then of course no react environments would need consideration too.

@aikar
Copy link
Author

aikar commented Apr 15, 2017

Though, Solving this would also require this plugin to include an extractor too (which is a good idea overall), as other tools would not know how to extract it.

@michael-ciniawsky
Copy link
Member

@aikar If you have time and interest to give it a shot please feel free to do so 😛

@xiao-hu
Copy link

xiao-hu commented May 1, 2017

I have another idea to solve this without the necessary to modify the plugin.
We just need to implement a simple function say assembleAsArray which turns this
assembleAsArray(__('Hello ${user}, Please ${call} or ${email} us for support'), {user: user, call : <a href={dial}>__('call')</a>, email: <a href={mailto}>__('email')</a>}) to an array ['Hello ', user, ', Please ', <a href={dial}>call</a>, ...].

And you can use it directly in React:

render() {
   <div>
      ...
      {assembleAsArray(__('Hello ${user}, Please ${call} or ${email} us for support'), {user: user, call : <a href={dial}>__('call')</a>, email: <a href={mailto}>__('email')</a>})}
      ...
   </div>
}

If you are not using React and just want to assemble strings, you can use it as well: assembleAsArray(__('Hello ${user}, Please ${call} or ${email} us for support'), {user: user, call : `<a href={dial}>${__('call')}</a>`, email: `<a href={mailto}>${__('email')}</a>`}).join('')

This could be also be a solution to #26 and #6.

@zlk89
Copy link

zlk89 commented Sep 13, 2017

@xiao-hu In my understanding, your idea won't solve the problem, because assembleAsArray has fixed the order of each part. But in some languages, order of each part might be different.
Actually your idea is the same as solution like the one below, which simply splits one sentence into multiple separate parts. (You can see this #26 (comment))

__('Hello ') + ${user} + __(', Please ')...

@cjol
Copy link

cjol commented Feb 27, 2018

assembleAsArray would not need to return an array with the same ordering as the input. For example:

Given this mapping:
Please call ${0} or email ${1} to contact us for more information
->
Pour plus de renseignements veuillez nous contacter par email au $[1} ou sur le ${0}

This code:
__asArray(`Please call ${<PhoneElement />} or email ${<EmailElement />} to contact us for more information`)

Should return:
[ "Pour plus de renseignements veuillez nous contacter par email au ", <EmailElement />, " ou sur le ", <PhoneElement /> ]

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants