Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using it with react_templates #18

Open
ekaradon opened this issue Aug 12, 2015 · 7 comments
Open

Using it with react_templates #18

ekaradon opened this issue Aug 12, 2015 · 7 comments

Comments

@ekaradon
Copy link

Hello,

I try to use this library in my application and I have a little issue. Indeed, I am using the (https://github.com/wix/react-templates)[react templates library] and it is using the extension .rt and not the .js or the .jsx extension. And I do not find how-to configure .i18nrc in order to change this pattern.

Cheers,

@Sy1v4in
Copy link

Sy1v4in commented Aug 12, 2015

Hi @jenseng,

i have a fix for this problem.
The AbstractProcessor uses a pattern to get files which could be configured (through the options).
But, in the i18nliner checks comment (file i18nliner-js/dist/lib/commands/check.js) you omit to transmit the configured pattern to the Processor in order to go through files you want:

      pattern: this.options.pattern,

In this case @ekaradon should call i18nliner export --pattern='*.rt' to make it work in his specific react templates context.

I create the jenseng/i18nliner-js#18 PR in the i18nliner-js project to fix that.

Cheers

@jenseng
Copy link
Owner

jenseng commented Aug 12, 2015

@Fraisse Thanks for the PR, I'll check it out!

@ekaradon Though even with that PR, I suspect react-i18nliner won't work in its current form with react-templates, since it preprocesses JSX, not HTML (I'm fairly certain both esprima and acorn would choke on .rt, and recast definitely would not generate valid .rt). Also, react-i18nliner uses the same processor for both regular .js files as well as .jsx (since JSX is a superset of JS). So I think we'd probably need a brand new pre-processor for .rt files.

That said, you should be able to use i18nliner-js today via javascript expressions, e.g.

<h1>{I18n.t("Hello World")}</h1>

Note that you'll want to run the i18nliner check and export commands on the javascript files generated by react-templates, not on the original .rt files.

@ekaradon
Copy link
Author

@jenseng Thanks for the answer,

Indeed, it does not work. It is stuck with an error complaining about a malformed string:

Error: Line 3: Adjacent JSX elements must be wrapped in an enclosing tag
[...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:7736
           throw e;
   at throwError ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:2819:21)
   at parseJSXElement ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:7226:13)
   at parsePrimaryExpression ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:3590:20)
   at parseLeftHandSideExpressionAllowCall ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:3683:61)
   at parsePostfixExpression ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:3723:20)
   at parseUnaryExpression ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:3790:16)
   at parseBinaryExpression ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:3880:16)
   at parseConditionalExpression ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:3940:16)
   at parseAssignmentExpression ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:4193:16)
   at parseExpression ([...]/node_modules/react-i18nliner/node_modules/recast/node_modules/esprima-fb/esprima.js:4250:16)

But I am not sure about what it would take to make it work and what need to be done. Is it possible to get further explanations about the pre-processing thing?

Also, I would like to know what the pre-processing outputs. I first thought that it was transforming the balise from:

<h2 translate="yes"> My title</h2>

to:

{i18n.translate("my_title")}

But if such was the case, It would works with esprima without complaints.

@ekaradon
Copy link
Author

Hello,

Would it be possible to get some clues about this topic? I am hesitating between using react-intl8 and this project but I would prefer to use this last one because the syntax is nicer. However, I am a bit stuck with this error of compilation and as I have no idea about how long it would take to support react-templates, I am in the dark.

@ailonn
Copy link

ailonn commented Aug 21, 2015

Hello,
I just met this complication on working on my project.
What is the fix planning ?
Thanks you for your work !

@jenseng
Copy link
Owner

jenseng commented Aug 24, 2015

@ekaradon / @ailonn: sorry for the delayed response, I've had a busy couple weeks...

react-i18nliner parses javascript files to find JSX elements with translate attributes. It expects the file to be valid JSX, and by default it uses esprima to do the parsing (though you can also use acorn). Although react-templates are similar to JSX, they are not equivalent, and thus will not be handled correctly by esprima or acorn. Key differences include class vs className, case-sensitivity of properties, attribute quoting, JSX's requirement that adjacent elements be nested in another one (that's the error you're seeing), etc.

So in its current state, there's not currently any way to use react-i18nliner on an .rtl file. And unfortunately, I don't have any immediate plans to support it. That said, I'd be happy to entertain pull requests that do add support. Though ideally, I think it would make even more sense as a separate NPM module (e.g. react-templates-i18nliner), and I'd be happy to provide some direction on how to go about it. react-templates uses cheerio to parse the HTML in your .rtl file into a tree, and then generates javascript from it.

So for react-templates-i18nliner, it seems like you would want to:

  1. Build a pre-processor that loads the DOM tree from your .rtl file via cheerio (just like react-templates does), and converts components w/ translate="yes" into I18n.ComponentInterpolators (see tests here). Ideally it would output .rtl back out, which react-templates would then covert into .js. This pre-processor would need to be used in your build process before react-templates runs.
  2. Build an i18nliner processor (using the pre-processor above) that extracts strings from those elements, so that they are picked up when you run i18nliner check or i18nliner export.

The pre-processor would have a lot of parallels to react-i18nliner's, the fundamental difference being it would operate on a cheerio tree instead of an esprima AST.

All that said, you should be able to use i18nliner as-is (e.g. <h2>{I18n.t("My Title")}</h2>), provided that you are running i18nliner check on the files after they're converted from .rtl to .js. From your error, it sounds like you're running i18nliner on the original .rtl files, which won't work due to the aformentioned incompatibilities between .rtl and .jsx. I don't know how you're building your assets (grunt/gulp/webpack/broccoli), but you'd want to point i18nliner at the intermediate or final .js files (since esprima/acorn cannot parse .rtl files). So you should probably 1. skip any hacks you have to process .rtl files and 2. tweak your .i18nrc to point at the files that have already been compiled by react-templates (maybe a tmp, dist, or public dir), e.g.

{
  "directories": ["dist"],
}

I hope that helps!

@ekaradon
Copy link
Author

@jenseng, thanks for your answer. It did help me to see more clearly how it works.
However, after thinking about it, I have decided to restart the project using only JSX through function which is imported from a different file in order to keep my definition of html outside of the component itself.

Indeed, react-templates was giving me some real headaches using it with different libraries like yours, react-router or even worse was giving me new bugs that pure JSX have not (like ignoring setting disabled).

Anyway, the problem is solved for my part and I will be using your library. I let you choose if you want to close this ticket or let it opened for newcomers.

Cheers!

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

No branches or pull requests

4 participants