miguel.nz

How to Merge Multiple JSON Files from WP CLI i18n

November 12, 2024   |   4 minutes read.

Handling translations in WordPress projects often involves using WP CLI commands to generate .pot and .json files. However, WordPress only reads a single JSON file per locale, which means that multiple translation files won’t be picked up correctly. This guide will walk you through the full process—from generating .pot and .json files to creating and merging them, and finally how to load those translations into your theme or plugin using wp_set_script_translations.

Overview of the Process

  1. Generate a .pot file using WP CLI.
  2. Convert the .pot file to .json files.
  3. Merge these .json files into one unified file for WordPress to read.
  4. Load the merged translations using wp_set_script_translations.

Step 1: Generate a .pot File

To create a .pot file that aggregates translatable strings from your project, use the WP CLI make-pot command:

wp i18n make-pot . languages/my-website-language.pot --exclude=node_modules,resources,theme.json,block.json,*.css,.scss --domain=my-website-language

Explanation:

  • .: The current directory as the source.
  • languages/my-website-language.pot: The output .pot file.
  • --exclude=...: Specifies folders and files to exclude.
  • --domain=my-website-language: The text domain of your project.

Step 2: Convert the .pot File to JSON Files

Use WP CLI to generate .json files from the .pot file:

wp i18n make-json languages/my-website-language.pot --output-dir=languages/js --no-purge

Explanation:

  • languages/my-website-language.pot: The source .pot file.
  • --output-dir=languages/js: Specifies the directory where .json files will be placed.
  • --no-purge: Prevents purging existing .json files.

Step 3: Merge JSON Files Using jq

Once you have multiple .json files, merge them into one using jq:

jq -s '
{
    "translation-revision-date": "2024-11-12 20:48+0700",
    "generator": "WP-CLI/2.11.0",
    "source": "merged",
    "domain": "my-website-language",
    "locale_data": {
        "messages": (reduce .[]["locale_data"]["messages"] as $item ({}; . * $item))
    }
}
' languages/js/*.json > languages/my-website-language-en_US-my-scripts.json

Explanation:

  • -s: Combines all .json files into an array.
  • reduce .[]["locale_data"]["messages"] as $item ({}; . * $item): Iterates over each messages section and merges them.
  • Outputs the merged file as my-website-language-en_US-my-scripts.json in the languages directory.

Step 4: Automate the Process with npm

Let’s streamline this by adding the merge command as a script in package.json:

Edit package.json

Add this to your scripts section:

"scripts": {
    "merge-json": "jq -s '{\"translation-revision-date\": \"2024-11-12 20:48+0700\", \"generator\": \"WP-CLI/2.11.0\", \"source\": \"merged\", \"domain\": \"my-website-language\", \"locale_data\": {\"messages\": (reduce .[][\"locale_data\"][\"messages\"] as $item ({}; . * $item))}}' languages/js/*.json > languages/my-website-language-en_US-my-scripts.json"
}

Step 5: Run the npm Script

To merge your JSON files, simply run:

npm run merge-json

This will create a single, comprehensive JSON file that WordPress can read, ensuring all your translations are included.

Step 6: Load Translations with wp_set_script_translations

Now that you have a merged JSON file, the next step is to ensure WordPress uses it for your theme or plugin. To do this, you need to load the translations with the wp_set_script_translations function.

Example Usage

In your theme or plugin, where you enqueue scripts, add the following code to load the merged translations:

function load_my_translations() {
    wp_enqueue_script( 'my-scripts', get_template_directory_uri() . '/js/my-scripts.js', array(), '1.0.0', true );
    
    // Load translations for the 'my-website-language' domain
    wp_set_script_translations( 'my-scripts', 'my-website-language', get_template_directory() . '/languages' );
}

add_action( 'wp_enqueue_scripts', 'load_my_translations' );

Explanation:

  • wp_enqueue_script: Enqueues your JavaScript file (my-scripts.js).
  • wp_set_script_translations: Loads the translations from the merged JSON file. The function parameters are:
    • The handle of the script ('my-scripts').
    • The text domain ('my-website-language').
    • The path to the directory containing the translations (in this case, get_template_directory() . '/languages').
  • Make sure your merged .json file (e.g., my-website-language-en_US-my-scripts.json) is in the /languages directory and is named according to the locale (e.g., en_US for American English).

Wrapping Up

Managing translations in WordPress requires careful handling of .pot and .json files. Since WordPress only supports one JSON file per locale, merging them is essential. Using jq and npm, you can automate this step and keep your internationalization streamlined. Once merged, wp_set_script_translations makes sure your translations are loaded correctly.

With these steps, you can easily manage and deploy translations in your WordPress theme or plugin, ensuring full multilingual support.

Amazing!