i18n Ideas
Message Syntax (Example)
simple-message = Some translated stuff
internal-reference = Internal Reference
interpolation = Of { internal-reference } and { $external }
plurals =
{ $unreadEmails ->
[one] You have one unread email.
*[other] You have { $unreadEmails } unread emails.
}
# `currency` is usually specified by the caller.
currencies =
{ NUMBER($price, style: "currency", currency: "EUR") }
dates =
{ DATETIME($date, day: "2-digit", month: "2-digit", year: "numeric") }
times =
{ DATETIME($time, hour: "2-digit", minute: "2-digit") }
Overlays (Nice to have)
some-message = Read our
<some-elem title="Privacy Policy">privacy policy</some-elem>.
+
<Localized id="some-message">
<a key="some-elem" href="https://www.mozilla.org/privacy" />
</Localized>
=
Read our
<a href="https://www.mozilla.org/privacy"
title="Privacy Policy">privacy policy</a>.
Proposed React API
import React from 'react'
import { Localized, Consumer } from 'localization'
interface MyComponentProps {
href: string
username: string
}
const MyComponent: React.SFC<MyComponentProps> = ({ href, username }) => (
<div>
<Localized id="some-text" props={{ username }}>
<a href={href} />
</Localized>
</div>
)
const MyInput: React.SFC<{}> = () => (
<Consumer>
{translate => (
<input
type="text"
placeholder={translate('some-placeholder', { required: true })} />
)}
</Consumer>
)
Codegen
// some-translation =
// Translation with { $string }
// and { NUMBER($number) }
// and { DATETIME($date) }
// turns into js code:
const Translations = {
["some-translation"]({ string, number, date }) {
const _number = …format(number)
const _date = …format(date)
return `Translation with ${string} and ${_number} and ${_date}`
}
}
// typescript definitons:
interface Props { string: string, number: number, date: Date }
interface Translate {
(id: 'some-translation', props: Props): string
(id: 'returns-react'): React.ReactNode
}
declare var translate: Translate
// … and similar for React Components
this is where the fun starts :-)
Project Plan
* Reuse existing MessageFormat or Fluent parser
-> figure out how much of the parser we can reuse
* Generate code from translation strings:
-> simple strings, strings with simple interpolations
-> more complex things like plurals, numbers, dates
* Generate typescript definitions with correct types
* Make overlays work with react
// simple-msg = Some simple Message.
// -internal = Internal
// interpolated = with { -internal } and { $external } Interpolation
function simpleMsg() {
return "Some simple Message.";
}
function _internal() {
return "Internal";
}
function interpolated({ external }) {
return "with " + _internal() + " and " + String(external) + " Interpolation";
}
export default {
"simple-msg": simpleMsg,
"interpolated": interpolated,
};
Progress
Vision for an internationalized future
By Arpad Borsos
Vision for an internationalized future
- 993