lingui / js-lingui Goto Github PK
View Code? Open in Web Editor NEW🌍 📖 A readable, automated, and optimized (3 kb) internationalization for JavaScript
Home Page: https://lingui.dev
License: MIT License
🌍 📖 A readable, automated, and optimized (3 kb) internationalization for JavaScript
Home Page: https://lingui.dev
License: MIT License
i18n.t
requires activated language to match one of the CLDR language codes. If not, i18n.t
will fail within messageformat.js, with an error message that is not so informative: "Localisation function not found for locale"
.
lingui can detect this when running the CLIlingui add-locale
, and when i18n.activate
is invoked.
hi! I understand that I can get the catalog from lingui
and send that to translation, as outlined here, however, not many translation services work with ICU message format. Can somebody point me to tools that work on Mac and are able to convert ICU to XLIFF, which is the translation industry standard?
Can somebody point me to translation services that accept (ie. are able to translate) ICU?
the ICU website mentions genrb
but I'm not sure it's available on mac.
also see formatjs/intl-messageformat#106
thanks!
lingui-react/Trans
renders empty components when babel plugin isn't installed.
// constructor of Trans
const translation = _this.getTranslation(props);
// something like this for NODE_ENV == development
// When babel-plugin is installed, props.children will be empty
if (!translation && props.children) {
console.warn('Missing babel-plugin')
}
Hey,
I'm playing with lingui at the moment and I'm pleased so far ;) Just two little DX-Items to reason about:
a) is there is any reason not to inject the method t() directly into the wrapped component by using WithI18n()-hoc? Would save the devs some repitive keystrokes!
b) I would love to see the naming of WithI18n changed to withI18n. Most devs are using capital first letters for classes which can be instantiated and most hocs are starting lowercase. One thing less to remember about.
Cheers & thanks
ICU format supports custom formats for numbers and dates.
Add Number
and Date
components which use Intl.dateTimeFormat
and Intl.numberFormat
(see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
Example:
<Trans><Number value={count} style="percent" /> of surface</Trans>
should result in:
"{count, number, percent} of surface"
It would be really nice if the cli could extract messages from .tsx?
files as well.
I'll expand this with issues as I find them, some may be unique to my project, so please bare with me:
When React Native's builder transforms the source files with Babel, it seems to fail when trying to transform the imported lingui-react
module. The transform succeeds if I remove the lingui-react
babel preset, and fails if I use it.
The provided components default to using <span>
which doesn't exist with React Native, if it's possible to detect the environment, it should use <Text>
instead, and pass through the style
prop rather than className
.
Hi, it seems to me that the .js files shipped in npm are not ES5, so it wont work with IE11 and older
$ npm install --save-dev lingui-i18n
$ cat node_modules/lingui-i18n/lib/compile.js | grep -Hn '{ language,'
(standard input):73: return formattedMessage(context({ language, params, formatStyles }));
it should be { language:language, params:params ...
And I guess there is the same problem with lingui-react
Thanks
The offset
prop must be a number, not a variable. Either warn or throw an error.
I try to use lingui-react
with a project that uses flow. But I cannot get it working with flow, because flow cannot find the library definition.
Currently I get the error:
import { I18nProvider } from 'lingui-react';
^^^^^^^^^^^^^^ lingui-react. Required module not found
I've tried all the suggestions spread around in issue trackers or blocks. But none of them works. Flow typed does also not create stub definitions for the library. It's also not possible to include it as lib from the node_modules/lingui-react/lib/
directory, because the definitions are mixed with normal JS files which flow doesn't like.
Do you have any suggestion how the lib could be used with flow?
I'm using create-react-app
with react-app-rewired
to enable making changes to webpack/babel without ejecting.
I've added the following config-overrides.js
file (a react-app-rewired
requirement):
module.exports = function override(config, env) {
let babelLoader;
const checkRule = rule => rule.loader && rule.loader.indexOf('babel-loader') > 0;
config.module.rules.every(rule => {
if (rule.oneOf) {
babelLoader = rule.oneOf.find(checkRule);
} else if (checkRule(rule)) {
babelLoader = rule.loader;
}
return !babelLoader;
});
babelLoader.options.babelrc = true;
return config
}
This make sure to load the .babelrc
file with the needed presets:
{
"plugins": [
"syntax-dynamic-import"
],
"env": {
"test": {
"plugins": [
"dynamic-import-node"
]
}
},
"presets": [
"env",
"react",
"lingui-react"
]
}
While this approach is working, extract
is failing with the following exception:
Extracting messages from source files:
C:\Development\partner_portal\client\config-overrides.js
C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babel-core\lib\transformation\file\index.js:590
throw err;
^
SyntaxError: C:/Development/partner_portal/client/node_modules/.bin/sha.js: Unexpected token, expected , (2:18)
1 | #!/bin/sh
> 2 | basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
| ^
3 |
4 | case `uname` in
5 | *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
at Parser.pp$5.raise (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:4454:13)
at Parser.pp.unexpected (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:1761:8)
at Parser.pp.expect (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:1749:33)
at Parser.pp$3.parseCallExpressionArguments (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:3564:12)
at Parser.pp$3.parseSubscripts (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:3533:31)
at Parser.pp$3.parseExprSubscripts (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:3504:15)
at Parser.pp$3.parseMaybeUnary (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:3474:19)
at Parser.pp$3.parseExprOps (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:3404:19)
at Parser.pp$3.parseMaybeConditional (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:3381:19)
at Parser.pp$3.parseMaybeAssign (C:\Users\ofirhe\AppData\Local\Yarn\config\global\node_modules\babylon\lib\index.js:3344:19)
Expected:
While I think this exception should be addressed, I think it would also be beneficial to allow specifying the files to include/exclude from the extraction process
Working on your first Pull Request? You can learn how from this free series How to Contribute to an Open Source Project on GitHub
There's a new documentation. However, I'm not a native english speaker and the documentation really needs some external proofreading.
List of pages:
All documentation is in docs
folder. It's build using Sphinx Document Generator and uses reStructuredText.
If you want to build documentation locally, you need to have Python installed.
pipenv
tool:pip install pipenv
pipenv install
After making any changes, simply run make html
inside docs
folder.
cd docs
make html
Need a help? Ping me on gitter. I live in Europe/Prague UTC+2 timezone and most of the time I answer questions on gitter instantly.
If I target the browser ie 11
in my babel-preset-env
config, then the translation which are based on template literals do not work. I think it's because babel-preset-env
pulls in transform-es2015-template-literals
. It generates then code like this:
var _templateObject = _taggedTemplateLiteral(['This field is required'], ['This field is required']),
_templateObject2 = _taggedTemplateLiteral(['Valid email required'], ['Valid email required']);
var defaultMessages = exports.defaultMessages = function defaultMessages(i18n) {
return {
isRequired: i18n.t(_templateObject),
isEmail: i18n.t(_templateObject2)
};
};
Without the transform-es2015-template-literals
plugin, it creates code like:
const defaultMessages = i18n => ({
isRequired: i18n._('This field is required'),
isEmail: i18n._('Valid email required')
});
If I'm right then you transform also template literals t function calls, but now the transform-es2015-template-literals
comes first and your transformation cannot be processed.
Firstly, this issue only appears in production (without development prop on provider) and only if this translation wasnt extracted & compiled (just running those commands, no translation).
Having this:
{i18n.t`narozen ${birthdate}`}
<Trans>narozen {birthdate}</Trans>
should render (and on localhost/dev renders):
narozen 8.8.1943
narozen 8.8.1943
but on productions shows:
narozen {birthdate}
narozen {birthdate}
Issue disappeared after just running extract & compile, however this shouldn't happen. I don't understand the innerworkings, but if it is not capable of rendering it correctly in production without compile, it should also fail on dev, so there is no bad surprise after deploy..
Just a small nitpick.
It's possible to use React.Component to render translation: <Trans render={Component}>...</Trans>
, but built-ins can be passed as elements only: <Trans render={<h1 />}>...</Trans>
.
Proposal: <Trans render="h1">...</Trans>
It's like 4 chars difference, but nice to have 😸
Followup to #53
Support custom formats of message catalog:
lingui-i18n
- i18n for Javascript projectslingui-react
- React components build on top of lingui-i18n
(resolved in #22)lingui-cli
and lingui-conf
lingui-loader
update
, withHash
props)React components are great because they care of updates after language/message changes. However, sometimes it's necessary to get string directly instead of React node tree, e.g: for element attributes, document.title
, etc. Sometimes it needs to be done even out of the ProvideI18n
context, e.g. inside sagas (from redux-saga).
const i18n = require('lingui-i18n')
// i18n.use(language: string, catalog: {[key: string]: string})
i18n.use('fr', {
"Hello World": "Salut le Monde",
"Hello, my name is {name}": "Salut, je m'appelle {name}"
})
// i18n.t(message: string, params: ?object): string
const translated = i18n.t('Hello world')
const withParams = i18n.t('Hello, my name is {name}', params={ name })
// i18n.compile(message: string): (params: ?object) -> string
const compiled = i18n.compile('Hello, my name is {name}')
compiled({ name })
This is the easiest use case. The only problem might be how to load messages into global object. Optionally add an API for precompiled messages.
This option isn't interesting at all, because many other libs already provides such functionality, but it's simple enough to keep it as a backup.
i18n.use
i18n.t
i18n.compile
Provide helper functions which mimic behavior of React components. Something like DSL for ICU message format:
const withParams = i18n.t`Hello, my name is ${name}`
const pluralize = i18n.plural({
value: count,
one: "# Book",
other: "# Books"
})
const complex = i18n.select({
value: gender,
female: plural({
value: numOfHosts,
offset: 1,
0: t`${host} does not give a party`,
1: t`${host} invites ${guest} to her party`,
2: t`${host} invites ${guest} and one other person to the party`,
other: t`${host} invites ${guest} and # other people to his party`
}),
male: plural({...}),
other: plural({...})
})
// "It happened {0, date, relative}"
const formats = i18n.t`It happened ${i18n.format.relative(value)}`
i18n.t
i18n.plural
i18n.select
Hi,
I have upgraded the package since last time, here is my config:
├─┬ [email protected]
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
├─┬ [email protected]
├─┬ [email protected]
│ └── [email protected]
├── [email protected]
But I encounter a problem when I do lingui extract
, Unexpected token
.
The code is fine and works when I yarn build
it or yarn start
it
yarn lingui v0.27.5
$ "/home/lfdmr/Dev/test/web_frontend/node_modules/.bin/lingui" "extract"
/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babel-core/lib/transformation/file/index.js:590
throw err;
^
SyntaxError: /home/lfdmr/Dev/test/web_frontend/src/App1/components/App.js: Unexpected token (6:2)
4 |
5 | const App = () => (
> 6 | <h1><Trans>Welcome App 1!</Trans></h1>
| ^
7 | )
8 |
9 | export default App
at Parser.pp$5.raise (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:4454:13)
at Parser.pp.unexpected (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:1761:8)
at Parser.pp$3.parseExprAtom (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:3750:12)
at Parser.pp$3.parseExprSubscripts (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:3494:19)
at Parser.pp$3.parseMaybeUnary (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:3474:19)
at Parser.pp$3.parseExprOps (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:3404:19)
at Parser.pp$3.parseMaybeConditional (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:3381:19)
at Parser.pp$3.parseMaybeAssign (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:3344:19)
at Parser.pp$3.parseParenAndDistinguishExpression (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:3828:26)
at Parser.pp$3.parseExprAtom (/home/lfdmr/Dev/test/web_frontend/node_modules/lingui-cli/node_modules/babylon/lib/index.js:3709:19)
error Command failed with exit code 1.
Thanks
Hey,
if I try to use lingui in a SSR environment and I'll get an exception, because lingui-formats directly accesses the window-object, which doesn't exist in a node-environment.
Trace:
ReferenceError: window is not defined
at Object. (/Users/bb/Development/xxx/src/node_modules/lingui-formats/dist/index.js:5:24)
at Module._compile (module.js:573:30)
at Module._extensions..js (module.js:584:10)
at Object.require.extensions.(anonymous function) [as .js] (/Users/bb/Development/xxxx/src/node_modules/babel-register/lib/node.js:152:7)
Is SSR simply not supported at the moment, is it a bug or am I missing something?
Empty translation ("translation": "",
) in language set as fallbackLanguage throws
if (input.charCodeAt(peg$currPos) === 123) {
^
TypeError: Cannot read property 'charCodeAt' of undefined
Hi, it's usual for some countries to have their own sub locale inside a language.
lingui-cli does appear to support this at the moment. Is it possible to add support?
Thanks again! And good job on the library!
Hi I have a problem with unpackCatalog
My catalog is
{
"Welcome App 1!": {
"translation": "Hi",
"origin": [
[
"src/App1/routes/Home/components/HomeView.js",
10
]
]
},
"Logo client": {
"translation": "Best client",
"origin": [
[
"src/App1/routes/Home/components/HomeView.js",
14
]
]
}
}
And when I use unpackCatalog(messages)
I get:
{
"languageData": {}
}
The key messages got undefined.
Lingui fires "Uncaught (in promise) ReferenceError: Trans is not defined" in a component that doesnt use Trans, only Plural (it is likely transformed?). But when I supply Trans, my linter is on fire (its not used) ...
I have to stick with:
import { withI18n, Trans, Plural } from 'lingui-react' // eslint-disable-line no-unused-vars
in every component...
lingui-react 1.1.0
anyway, great job on the repo!
In order to remove dependency on the i18n package, I tried making a single-point-of-entry file for i18n.
Something along the lines of:
import {withI18n, Trans} from 'lingui-react'
export {
Trans,
withI18n
}
However, this resulted in two problems:
lingui extract
)lingui-react preset is probably missing in babel config...
although lingui-react is not missing in babel config file (without the wrapping file, the warning is gone).
Also, all strings were seen as empty in the application.
Is this unsupported? Am I doing it wrong?
If I add the browser ie 11
to my babel-preset-env config, then I get some errors if I try to build my application:
[info] Module build failed: TypeError: ...: Cannot read property 'reduce' of undefined
[info] at collectMessage (...\node_modules\babel-plugin-lingui-extract-messages\lib\index.js:24:27)
I'm not sure if this has to do with js-lingui or if it's an issue from another component.
Children of these components are ignored. Either warn or throw an error.
Just to make it clear, there're two i18n APIs:
lingui-i18n
, for vanilla javascript (i18n.t'Hello World'
). This works without React and it's a base for future integrations.lingui-react
, for React components (<Trans>Hello World</Trans>
) which under the hood uses lingui-i18n
, so it's possible to use it for translation of attributes (<Trans title={i18n.t'Title'}>Hello World</Trans>
)React is all about rendering data. When data changes, React renders updates. Given example below:
<span>{i18n.t`Hello World`}</span>
<Trans>Hello World</Trans>
when language or message catalog changes, the span
(or probably parent component) is responsible for update, while Trans
take care of it itself. When parent component is optimized using shouldComponentUpdate
, the Trans
component will update the translated message even when parent skips update.
Reason 1: Using Trans
component shifts responsibility from parent to Trans
component itself. As a developer, you don't have to worry about skipped updates.
Second reason are inline components. Using Trans
component you can go wild a do things like this:
<Trans>
Any component is <strong className="green">valid</strong> here, even <Link>custom</Link> ones.
</Trans>
Example above will result in single entry in your message catalog: Any component is <0>valid</0> here, even <1>custom</1> ones.
This has several advantages:
i18next
, formatjs
) translate content of inline components separately which is unfortunate for translators.Reason 2: First-class support for inline components. As a developer, you can use JSX as you're used to. As a translator, you see the full message.
In future I'm planning further optimization, when message is rendered to React components tree and when props changes (like values, params) the message isn't parsed from scratch, but React handle update itself. Right now, message itself is cached, but inline components are rendered on each update.
// key
i18n.t`component.title`
// message in source language
i18n.t`Title`
Both approaches have pros & cons. I never settled to either solution. I'm trying to support both approaches:
// Key
<Trans id=`msg.hello`>Hello World</Trans>
// becomes {'msg.hello': 'Hello World'} for English
// Message
<Trans>Hello World</Trans>
// becomes {'Hello World': 'Hello World'} for English
I'm using second approach in examples because it's easier to start with.
Following https://lingui.gitbooks.io/js/tutorials/react.html got me to:
Now we're ready to extract messages:
$ lingui extract
And then it shows nicely formatted language file:
{
"Message Inbox": "",
"See all <0>unread messages</0> or <1>mark them</1> as read.": "",
"{messagesCount, plural, one {There's {messagesCount} message in your inbox.} other {There're {messagesCount} messages in your inbox.}}": "",
"Last login on {lastLogin, date}": ""
}
However mine looks very different, containing origin values (it does compile though):
{
"StringOne": {
"translation": "",
"origin": [
[
"src\\components\\common\\Header.js",
26
]
]
},
"StringTwo": {
"translation": "",
"origin": [
[
"src\\components\\common\\Header.js",
53
]
]
}
}
What am I doing wrong? I was just following the tutorial.
First off, thanks for this project. It's pretty much exactly what I wished for while being significantly smaller than other implementations.
const date = new Date(new Date() - 30 * 1000)
magic(date) -> '30 seconds ago'
Is there any way (now or planned) to format a date as a relative time string? Or is there another preferred way of dealing with these - I am thinking about a custom component and translation messages?
Or to word it differently, if you think that its best dealt with with a custom component, would you be interested to have something like that in the docs?
value
props is required for these components and essential for generating of ICU message id. Either warn or throw an error.
Trans
component gets messages from context. Relying on an update of context is unsafe. I18nProvider
should notify Trans
components using listen/subscribe pattern.
Bonus: Figure out how HMR is working with message catalogues.
I had a similar issue earlier, but now I have tried everything, with zero results :/
After updating lingui-react to 1.1.1 and updating babel plugin to the latest version, some of my translation stopped working (in production -> dev = undefined). Only those, which have a variable or component inside and are untranslated, eg.
"Výsledky hledání pro <0>{searchedString}</0>": {
"translation": "",
"origin": [
[
"src\\components\\pages\\SearchResults.js",
34
]
]
}
SearchResults.js:
<Trans>
Výsledky hledání pro <span className={cls.highlight}>{searchedString}</span>
</Trans>
It renders Výsledky hledání pro {searchedString}
. I tried to extract & compile my catalog several times.. only thing that works, is adding a translation, which is impossible for me to do for every such translation for every language at this point of this project 😞 .
I hope it has a simple solution or I am doing something very wrong.
Extract command crashed on one of my components (helper one, without any translations), had to remove it from parsing via ignore pattern. The reason it is crashing is completely strange to me.
The entire file (src\components\helpers\SearchableSelect.js
):
import React, { PureComponent } from 'react'
import cls from '../../../styles/layout.less'
import InputLabel from 'material-ui/Input/InputLabel'
import FormControl from 'material-ui/Form/FormControl'
import FormHelperText from 'material-ui/Form/FormHelperText'
import Select from 'react-select'
import 'react-select/dist/react-select.css'
export default class SearchableSelect extends PureComponent {
render() {
const {name, value, options, label, helperText, changeHandler} = this.props
let labelProps = {}
if (value) {
labelProps.shrink = true
}
return (
<FormControl className={cls.formControl + ' ' + cls.selectField}>
<InputLabel htmlFor={name} className={cls.inputLabel} {...labelProps}>{label}</InputLabel>
<Select
className={cls.select}
name={name}
value={value}
options={options}
placeholder=''
noResultsText={false}
onChange={changeHandler}
/>
{helperText && <FormHelperText className={cls.helperText}>{helperText}</FormHelperText>}
</FormControl>
)
}
}
The error (@ lingui-cli\node_modules\babel-core\lib\transformation\file\index.js:590
):
SyntaxError: ... /src/components/helpers/SearchableSelect.js: Missing fallback argument 'other'.
17 | <FormControl className={cls.formControl + ' ' + cls.selectField}>
18 | <InputLabel htmlFor={name} className={cls.inputLabel} {...labelProps}>{label}</InputLabel>
> 19 | <Select
| ^
20 | className={cls.select}
21 | name={name}
22 | value={value}
at File.buildCodeFrameError (lingui-cli\node_modules\babel-core\lib\transformation\file\index.js:427:15)
at PluginPass.buildCodeFrameError (lingui-cli\node_modules\babel-core\lib\transformation\plugin-pass.js:64:53)
at processElement (lingui-cli\node_modules\babel-plugin-lingui-transform-react\dist\index.js:186:20)
at PluginPass.JSXElement (lingui-cli\node_modules\babel-plugin-lingui-transform-react\dist\index.js:396:21)
at newFn (lingui-cli\node_modules\babel-traverse\lib\visitors.js:276:21)
at NodePath._call (lingui-cli\node_modules\babel-traverse\lib\path\context.js:76:18)
at NodePath.call (lingui-cli\node_modules\babel-traverse\lib\path\context.js:48:17)
at NodePath.visit (lingui-cli\node_modules\babel-traverse\lib\path\context.js:105:12)
at TraversalContext.visitQueue (lingui-cli\node_modules\babel-traverse\lib\context.js:150:16)
at TraversalContext.visitMultiple (lingui-cli\node_modules\babel-traverse\lib\context.js:103:17)
at TraversalContext.visit (lingui-cli\node_modules\babel-traverse\lib\context.js:190:19)
at Function.traverse.node (lingui-cli\node_modules\babel-traverse\lib\index.js:114:17)
Parse ICU message as a string and return a tree of React elements. This transformation allows using custom Format elements #6 and also speeds up rendering of messages with inline components.
Hello,
My build pipeline is something like: lint > flow > test > build.
I would like to add checks for missing messages.
lingui extract
produces a nice catalog statistics, that show if there are some missing translations.
Problem is, I can't plug it to my pipeline. I need a check that exits with error code, if there are some missing translations.
I'd like my pipeline to abort build and show error in this case.
Hopefully, this won't be hard to implement.
Thanks!
Followup from #53
Sometimes it's necessary to mark strings which will be translated in the future, but leave them intact for now:
import { Trans, noop } from 'lingui-react'
const menu = [
{ to: '/about', title: noop('About') },
{ to: '/contact', title: noop('Contact') },
]
// later in the code
const Menu = () =>
<div>{
menu.map(item =>
<Link to={item.to}>
<Trans id={item.title} />
</Link>)
}</div>
Having these two translations of the same word in a component
<input type="text" className="search__input" placeholder={i18n.t`Hledej`} />
<Trans>Hledej</Trans>
the placeholder is not updating correctly, while the usual <Trans>
is. The component is updated upon language change, as well as the component with Provider. The placeholder is updated always on a second update (eg. a navigation), which causes it to be always in the wrong language when toggling languages (is delayed by 1 update). There is no problem with the <Trans>
component.
Is there a way to resolve or bypass this problem (other than forcing update on didUpdate in every component...) ?
Thank you.
UPDATE:
Problem is resolved using Component instead of PureComponent, you are probably using context updates, which are ignored in PCs.
The library make-plural
uses a new Function construct, which violates the script-src CSP rule.
Please see: https://developer.chrome.com/extensions/contentSecurityPolicy#relaxing-eval
Evaluated JavaScript
The policy against eval() and its relatives like setTimeout(String), setInterval(String), and new Function(String) can be relaxed by adding 'unsafe-eval' to your policy:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
However, we strongly recommend against doing this. These functions are notorious XSS attack vectors.
I've opened an issue upstream eemeli/make-plural#10
Hi,
I just upgraded to the new version 1.0.0 of lingui, and I am encountering a problem with the command
lingui add-locale en
I got this messages if I don't create my locale path
yarn lingui v0.27.5
$ "/home/lfdmr/Dev/project/web_frontend/node_modules/.bin/lingui" "add-locale" "en"
fs.js:923
return binding.mkdir(pathModule._makeLong(path),
^
Error: ENOENT: no such file or directory, mkdir 'src/locales/en'
And when I create the path I got:
yarn lingui v0.27.5
$ "/home/lfdmr/Dev/project/web_frontend/node_modules/.bin/lingui" "add-locale" "en"
fs.js:923
return binding.mkdir(pathModule._makeLong(path),
^
>Error: EEXIST: file already exists, mkdir 'src/locales'`
Here is my config:
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
├─┬ [email protected]
├─┬ [email protected]
│ └── [email protected]
├── [email protected]
lingui extract
command could remove dead translations from messages.json that do not appear in the source code anymore (possibly with a switch)
The documentation states :
lingui-i18n still exports the default instance of I18n class, this remains unchanged:
import i18n from 'lingui-i18n'
But if I try to import it in my tests I get the warning:
"export 'default' (imported as 'i18n') was not found in 'lingui-i18n'
Same if I try to import the instance in the application itself.
Importing setupI18n
works as expected.
import { setupI18n } from 'lingui-i18n';
const i18n = setupI18n();
Trans
might either require a component at index
which is missing or use fewer components than is provided. Warning/error should be raised in both cases.
In the new [email protected]
parameters sourceLocale
and fallbackLocale
(as per https://lingui.gitbooks.io/js/content/ref/cli.html) are considered "unknown":
$ npm install lingui-cli -g --silent
/usr/local/bin/lingui -> /usr/local/lib/node_modules/lingui-cli/dist/lingui.js
+ [email protected]
added 102 packages in 9.13s
$ lingui extract
Extracting messages from source files…
● Validation Warning:
Unknown option "fallbackLocale" with value "cs" was found.
This is probably a typing mistake. Fixing it will remove this message.
See https://l.lingui.io/ref-lingui-conf for a list of valid options
● Validation Warning:
Unknown option "sourceLocale" with value "cs" was found.
This is probably a typing mistake. Fixing it will remove this message.
See https://l.lingui.io/ref-lingui-conf for a list of valid options
Collecting all messages…
Writing message catalogues…
Messages extracted!
configuration:
"lingui": {
"fallbackLocale": "cs",
"sourceLocale": "cs",
"localeDir": "<rootDir>/locales",
"srcPathDirs": [
"<rootDir>/src"
],
"srcPathIgnorePatterns": [
"/node_modules/",
"/helpers/"
]
}
However it does not affect functionality.
I haven't had much luck doing
const component = (props) => {<Trans>Hello {props.user}</Trans>);
it always renders Hello undefined
. However if I change it to
const component = ({user}) => (<Trans>Hello {user}</Trans>);
I get Hello Foo
, which is the output I expected in the first case. Is this a bug that's easy to fix? I'll be happy to PR if you point me in the right direction.
Given
const resultCount = 0
This component:
<Plural
value={resultCount}
zero={`Nenalezen žádný koncert`}
one={`Nalezen jeden koncert`}
few={`Nalezeny ${resultCount} koncerty`}
other={`Nalezeno ${resultCount} koncertů`}
/>
renders Nalezeno 0 koncertů
While this component:
<Plural
value={resultCount}
_0={`Nenalezen žádný koncert`}
one={`Nalezen jeden koncert`}
few={`Nalezeny ${resultCount} koncerty`}
other={`Nalezeno ${resultCount} koncertů`}
/>
renders Nenalezen žádný koncert
Tested only in dev environment, lingui-react 1.1.0.
Nalezeno <span className={cls.highlight}>{resultCount}</span> koncertů
Interesting feature. Plurals have next to ordinal and cardinal also third category: range: http://www.unicode.org/cldr/charts/28/supplemental/language_plural_rules.html
From: formatjs/formatjs#868
I've been thinking about namespaces for a while and i18next/react-i18next#199 (comment) made me to write it down.
Sometimes are messages split in several message catalogs. Both catalogs might contain message with the same ID and it that case it would be overwritten without namespacing messages from different catalogs.
This feature already exists in most i18n libs.
What's more interesting and what I actually would like to do are local namespaces. There're two possible use cases:
Imagine you have a React component and you want to ship translations with it. Ideally, developer using this component should just spin up it's own i18n provider to activate language, but the messages should be loaded directly from component. All translations inside this components should be tied to the component only.
lingui-cli
should only extract messages from 3rd party components if it isn't translated in some language, otherwise it should ignore it
As we split the code, we should be able to split the message catalog. This should be fully automated: only messages in bundled code are added to the bundle.
Hi,
I encounter a problem when I use WithI18n, I got the following messages:
./src/App1/routes/Home/components/HomeView.js
Module build failed: SyntaxError: Unexpected token, expected ; (6:45)
4 | import './HomeView.scss'
5 |
> 6 | export const HomeView = WithI18n()({ i18n }) => {
| ^
7 | return (
8 | <div>
9 | <h3><Trans>Welcome App 1!</Trans></h3>
@ ./src/App1/routes/Home/index.js 1:0-45
@ ./src/App1/routes/index.js
@ ./src/App1/main.js
The code is
import React from 'react'
import { WithI18n, Trans } from 'lingui-react'
export const HomeView = WithI18n()({ i18n }) => {
return (
<div>
<h3><Trans>Welcome App 1!</Trans></h3>
<img
src="/static/logos/logo_client.png"
alt={i18n.t`Logo client`}
/>
</div>
)
}
export default HomeView
My configuration is:
├─┬ [email protected]
│ ├── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
├─┬ [email protected]
│ └── [email protected]
├── [email protected]
And I use Redux with this starter kit
So I tried import i18n from 'lingui-i18n'
and everything works.
So why one should use WithI18n ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.