Skip to content

Instantly share code, notes, and snippets.

@shadyvb
Created February 11, 2021 23:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shadyvb/f2c243bd83569d8cf9bf78c8269cc76b to your computer and use it in GitHub Desktop.
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.
<?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 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