Describe the bug
Both react FilePond and lingui.js use {} chars to mark variables.
When you try to add FilePonf label for translations you get an error because lingui expect you will pass a value of the variable, but it actually FilePond's variable.
To Reproduce
Steps to reproduce the behavior, possibly with minimal code sample, e.g:
import { t } from '@lingui/macro';
import { I18n } from '@lingui/react';
import { FilePond } from 'react-filepond';
export default function App() {
return (<I18n>
{({ i18n }) => (<FilePond
โฆ
labelMaxFileSize={i18n._(t`Maximum file size is {filesize}`)} />))}
</I18n>);
}
You will get TypeError: Cannot read property 'filesize' of undefined โ it came from /node_modules/@lingui/core/cjs/core.development.js:134. I suppose that lingui.js think that filesize is lingui.js variable and expect filesize value should be passed. But it's should be passed by FilePhond.
Expected behavior
It would be nice to escape {} somehow.
I have tried / and // but I either get an error, either it just doesn't translate it.
Additional context
Add any other context about the problem here.
lingui --version 1.4.5npm list babel-core$ npm list babel-core
[email protected] /Users/silentimp/Work/instapro-client
โโโฌ [email protected]
โโโ [email protected]
.babelrc) or framework you use (Create React App, Meteor, etc.){
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"debug": false,
"useBuiltIns": "usage",
"targets": {
"browsers": [">0.2%", "not dead", "not ie < 11", "not op_mini all"]
}
}
],
"next/babel"
],
"plugins": ["macros"]
}
LinguiJS uses ICU MessageFormat. Could you please try escape argument using apostrophes?
Maximum file size is '{filesize}'
@tricoder42 I have tried to do it this way:
import { t } from '@lingui/macro';
import { I18n } from '@lingui/react';
import { FilePond } from 'react-filepond';
export default function App() {
return (<I18n>
{({ i18n }) => (<FilePond
โฆ
labelMaxFileSize={i18n._(t`Maximum file size is '{filesize}'`)} />))}
</I18n>);
}
After extractions I get inside message.json:
โฆ
"Maximum file size is '{filesize}'": "Maximum file size is '{filesize}'",
"Maximum total file size is '{filesize}'": "Maximum total file size is '{filesize}'",
โฆ
But I still get an error:
ร
TypeError: Cannot read property 'filesize' of undefined
ctx
./node_modules/@lingui/core/cjs/core.development.js:134
131 | var formatters = defaultFormats(language, locales, languageData, formats);
132 |
133 | var ctx = function ctx(name, type, format) {
> 134 | var value = values[name];
135 | var formatted = formatters[type](value, format);
136 | var message = isFunction(formatted) ? formatted(ctx) : formatted;
137 | return Array.isArray(message) ? message.join("") : message;
โฆ
Looks like this is present in the newer version of messageformat-parser but not in version 2.0.0 that @lingui/core uses.
Here's the messageformat-parser changelog
Actually, I think this is an actual non-production bug with how the lingui compiler parses escaping characters that would exist even after upgrading to [email protected].
In [email protected], using \\ instead of ' should escape the curly braces
(i.e. Maximum file size is \\{filesize\\}).
In non-production env, messages that are compiled to strings are compiled twice, once on I18n.load and again on I18n._.
Since the messageformat-parser removes the escape characters, the redundant parsing causes the escape characters to be ignored.
parse(parse('Maximum file size is \\{filesize\\}'))
โโโโโโโโ
parse('Maximum file size is {filesize}')
โโโโโโโโ
compiled message function that treats 'filesize' as an argument
A solution would be to try to avoid compiling messages twice, either by always compiling to a functiion instead of sometimes a string or avoiding compiling on I18n._ if this.messages[id] exists.
In fact, I was wrong earlier; [email protected] actually contains support for ' as an escape character already which might explain the behavior in #421.
@tricoder42 This is fixed in v3. Should this be closed?
@hjylewis Yeah, good point! ๐