Created
February 11, 2021 23:29
-
-
Save shadyvb/f2c243bd83569d8cf9bf78c8269cc76b to your computer and use it in GitHub Desktop.
Support for single-file JS translation files in loco-translate plugin, includes a patch of the plugin to allow hijacking the file generation process.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Register actions and filters | |
*/ | |
function bootstrap() : void { | |
// Setup script translations | |
add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\setup_script_translations' ); | |
// Filter the script translation lookup process to avoid linking to relative path names | |
add_filter( 'load_script_translation_file', __NAMESPACE__ . '\filter_script_translation_path', 10, 3 ); | |
// Fix loco-translate JSON file generation in v2.5 (uses patched/injected filter) | |
add_filter( 'pre_loco_write_json', __NAMESPACE__ . '\\loco_generate_json_translation_file', 10, 4 ); | |
} | |
/** | |
* Load JSON translation files for JS | |
* | |
* @return void | |
*/ | |
function setup_script_translations() : void { | |
wp_set_script_translations( 'YOUR_SCRIPT_HANDLE', 'YOUR_DOMAIN', WP_CONTENT_DIR . '/PATH/TO/YOUR/LANGUAGES/FOLDER' ); | |
} | |
/** | |
* Filter script translation path to use uploads folder | |
* | |
* @param string $file | |
* @param string $handle | |
* @param string $domain | |
* | |
* @return void | |
*/ | |
function filter_script_translation_path( string $file, string $handle, string $domain ) : string { | |
$locale = determine_locale(); | |
if ( $domain === 'YOUR_DOMAIN' ) { | |
$file = WP_CONTENT_DIR . '/PATH/TO/YOUR/LANGUAGES/FOLDER/YOUR_DOMAIN-' . $locale . '.json'; | |
} | |
return $file; | |
} | |
/** | |
* Generate JSON translations of a bundle in a single file without hashes | |
* | |
* This fixes an issue with the way WordPress / Loco generates files, requiring exact file paths on | |
* production as during the generation process, which is broken by any build/concatenation process like webpack. | |
* | |
* @param \Loco_gettext_Data $po | |
* @param \Loco_package_Project $project | |
* @param \Loco_gettext_Compiler $compiler | |
* | |
* @see \Loco_gettext_Compiler::writeAll for the injected action to trigger this (loco_written_compiled_translations) | |
* @see \Loco_gettext_Compiler::writeJson for the JSON file writing process | |
* @see \Loco_gettext_Data::msgjed for the formatting process of the JSON file | |
* | |
* @action loco_written_compiled_translations | |
* | |
* @return void | |
*/ | |
function loco_generate_json_translation_file( $result = null, \Loco_package_Project $project = null, \Loco_gettext_Data $po, \Loco_fs_File $pofile ) { | |
// :shrug: | |
if ( empty( $project ) ) { | |
return; | |
} | |
$domain = $project->getDomain()->getName(); | |
$name = $pofile->filename() . '.json'; | |
$jsonfile = $pofile->cloneBasename( $name ); | |
// 1. Collect all JS translations from the PO file | |
$data = []; | |
foreach ( $po->exportRefs( '\\.js' ) as $ref => $fragment ) { | |
$data = array_merge( $data, $fragment->exportJed() ); | |
} | |
// 2. Get headers from PO file | |
$head = $po->getHeaders(); | |
// 3. Format the file content in JSON | |
$formatted = json_encode( [ | |
'translation-revision-date' => $head['PO-Revision-Date'], | |
'generator' => $head['X-Generator'], | |
'source' => '', | |
'domain' => $domain, | |
'locale_data' => [ | |
$domain => $data, | |
], | |
] ); | |
// 4. Save the JSON file with the same name of the PO file but with .json extension | |
try { | |
$fs = new \Loco_api_WordPressFileSystem; | |
$fs->authorizeSave( $jsonfile ); | |
$jsonfile->putContents( $formatted ); | |
} catch ( \Loco_error_WriteException $e ) { | |
\Loco_error_AdminNotices::debug( $e->getMessage() ); | |
\Loco_error_AdminNotices::warn( sprintf( __( 'JSON compilation failed for %s', 'loco-translate' ), $ref ) ); | |
} | |
$jsons = new \Loco_fs_FileList; | |
$jsons->add( $jsonfile ); | |
return $jsons; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This patch for loco-translate v2.5 adds a filter to shortcircuit the JSON files generation process of loco-translate. | |
Use it with vaimo/composer-patches to apply it to the plugin via composer, or apply the changes manually otherwise. | |
@package wpackagist-plugin/loco-translate | |
diff -ru ./src/gettext/Compiler.php ./src/gettext/Compiler.php | |
--- ./src/gettext/Compiler.php 2021-02-12 00:49:38.000000000 +0200 | |
+++ ./src/gettext/Compiler.php 2021-02-12 00:53:49.000000000 +0200 | |
@@ -102,6 +102,19 @@ | |
$pofile = $this->files->getSource(); | |
$base_dir = $project->getBundle()->getDirectoryPath(); | |
$domain = $project->getDomain()->getName(); | |
+ /** | |
+ * Filter to allow external handling of JSON file generation | |
+ * | |
+ * @param \Loco_gettext_Data $po | |
+ * @param \Loco_package_Project $project | |
+ * @param \Loco_gettext_Compiler $compiler | |
+ * | |
+ * @return Loco_fs_FileList|null | |
+ */ | |
+ $pre = apply_filters('pre_loco_write_json',null,$project,$po,$pofile); | |
+ if( $pre !== null) { | |
+ return $pre; | |
+ } | |
/* @var Loco_gettext_Data $fragment */ | |
foreach( $po->exportRefs('\\.js') as $ref => $fragment ){ | |
// Reference could be source js, or minified version. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment