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

make-json does not work for .jsx files #200

Closed
EvanShaw opened this issue Dec 17, 2019 · 5 comments · Fixed by #284
Closed

make-json does not work for .jsx files #200

EvanShaw opened this issue Dec 17, 2019 · 5 comments · Fixed by #284

Comments

@EvanShaw
Copy link

I have no problem generating .pot files for php and jsx files with the following command: wp i18n make-pot . languages/messages.pot . Then after merging with my .po files I get something like the following:

#: src/Admin/Settings.php:179
#: src/Views/ConfirmPage/Wrapper.php:87
#: src/Admin/Settings.jsx:12
msgid "Test Publishable Key"
msgstr "Test Publishable Key"

jsx is parsed correctly and everything seems fine. However, when I run wp i18n make-json languages --no-purge, no files are created.

Changing jsx extensions to js circumvents this issue, but I would expect if make-pot can parse jsx then make-json can detect .po comments ending in jsx

@EvanShaw
Copy link
Author

After doing some digging, I'm gonna follow up on my own issue here which seems to be closely related to #177

People compiling their JS/JSX/TS with Webpack are likely to run into this problem since it's not very obvious even after reading these two great articles: (1, 2).

Basically, make-pot will parse js/jsx files, but the comment containing the file path and line number...

#: src/Admin/Settings.jsx:12
msgid "Test Publishable Key"
msgstr "テスト公開可能キー"

... is not the same as the bundle file generated by Webpack that you enqueue. If you're like me and trying to auto-generate your json translation files with make-json, the above will not work because make-json uses .po comments to create json files of the form ${textdomain}-${locale}-${js_file_relative_path_md5}.json, where md5 needs to be the md5 of the relative path to the file that you are actually enqueueing, or WordPress will not load it.

In my case, the script that I am actually enqueuing is a Webpack bundle located at dist/webhookSettings.js (relative to my plugin dir). This is what WordPress expects the md5 to be of. The way I got around this is by only including my bundle files when using make-pot so that the .po comments look like this:

#: dist/webhookSettings.js:31970
msgid "Test Publishable Key"
msgstr "テスト公開可能キー"

After doing this, make-json generates files with the correct md5 hash.

It looks like this issue is already being discussed elsewhere (#174, #127), but I think it goes without saying that parsing minified bundle files as a workaround is not ideal.

@swissspidy
Copy link
Member

@EvanShaw The MD5 hash issue is indeed being discussed elsewhere and is not trivial to solve. But I don't see why the command would not create any JSON file at all. Can you please clarify whether this is about the wrong file name issue or if no JSON files are actually created?

@EvanShaw
Copy link
Author

@swissspidy Sorry for derailing a bit from the initial issue. JSON files are indeed not created by make-json if all of the files which translations were parsed from are .jsx files.

make-pot will parse .jsx files just fine, but when looking at the source of MakeJsonCommand.php, it appears that .jsx files are not checked for.

Lines 133 - 149:

// Find all unique sources this translation originates from.
$sources = array_map(
	function ( $reference ) {
		$file = $reference[0];
		if ( substr( $file, - 7 ) === '.min.js' ) {
			return substr( $file, 0, - 7 ) . '.js';
		}
		if ( substr( $file, - 3 ) === '.js' ) {
			return $file;
		}
		return null;
	},
	$translation->getReferences()
);

As it stands, .jsx files can't be understood natively by a browser as far as I know... and since the md5 generated by make-json must match the file you actually enqueue (which won't be jsx), I think it probably makes most sense to just not parse .jsx files in the make-pot command. What do you think?

@LC43
Copy link

LC43 commented Feb 18, 2020

just happened to me too.

on my .po. note the .jsx extension:

#: src/components/AuthorInfo.jsx:9
msgid "About"
msgstr "Sobre"

src/components/AuthorInfo.jsx:9

    var about = __( 'About', 'preact-author' );

dist/main.js

...
_("h3",{className:"author-info__name"},_("span",null,J("preact-author",void 0,"About")," ")," ",_("a",{href:this.props.link},this.props.name)) 
...

assets.php

	wp_enqueue_script( 'preact-author-script', plugin_dir_url( __FILE__ ) . '../dist/main.js', [ 'wp-i18n' ], '1.0', true );
	wp_set_script_translations( 'preact-author-script', 'preact-author' );

things i tried:

1 if i change the to .js in the .po file, it does generate a json but with the md5 of 'src/components/AuthorInfo.jsx'. ❌

2 using --include to make-pot to parse dist/ :x:

@dingo-d
Copy link

dingo-d commented Nov 21, 2020

The same thing happened to me.

I'm bundling .jsx file that is located in the assets/dev/scripts/ folder, using webpack to a file called application-somehashhere.js in my /assets/public folder.

My .po file points to .jsx files in the dev folder, and when I try running the make-json command, nothing happens.

Any workaround for this? Without it, my plugin options are basically untranslatable (my plugin settings page is built using GB components 😬 )

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

Successfully merging a pull request may close this issue.

4 participants