1

I'm learning how to make plugins, and Thanks to Sally CJ managed to get translation working on the PHP files, and the Gutenberg Block... (If any need help on this check here ) But, I can't make it work on the plugin settings page using React.

Couldn't find any info about how to do it. Also checked the library @wordpress/react-i18n , but if I load it everything stops working.

This is part of the code. It's a simple plugin to learn. It loads well, adds the block to the editor and the block is localized, adds an admin menu page with a div that React replaces, but the localization inside this React doesn't work.

Thanks.

Structure:

/my-block/
      /build/
          - index.js
          - index.js.map
          - index.asset.php
      /src/
          - index.js
      /languages/
          - my-block-es_ES.mo
          - my-block-es_ES.po
          - my-block-es_ES.pot
          - my-block-es_ES-dfbff627e6c248bcb3b61d7d06da9ca9.json

       - block.json
       - my-block.php
       - package.json
       - ...

Main PHP:

<?php

/**
 * Plugin Name:       My Block
 * Requires at least: 6.1
 * Requires PHP:      7.0
 * Version:           1
 * Text Domain:       my-block
 */

function create_block_my_block_block_init()
{
    load_plugin_textdomain('my-block', false, dirname(plugin_basename(__FILE__)) . '/languages');

    register_block_type(__DIR__);
}
add_action('init', 'create_block_my_block_block_init');

function script_translations()
{
    $script_handle = generate_block_asset_handle('my-block/local', 'editorScript');
    wp_set_script_translations(
        $script_handle,
        'my-block',
        plugin_dir_path(__FILE__) . 'languages'
    );
}
add_action('enqueue_block_editor_assets', 'script_translations');

function create_admin_menu()
{
    add_menu_page(
        'my-block',
        __('My Block', 'my-block'),
        'manage_options',
        'my-block',
        'my_menu_page_template',
        'dashicons-buddicons-replies'
    );
}
add_action('admin_menu', 'create_admin_menu');

function my_menu_page_template()
{
    echo '<div id="wrap">';
        echo '<div id="my-block">' . __('My Block Local', 'my-block') . '</div>';
    echo '</div>';
}

function my_enqueue_admin_scripts()
{
    $asset = include plugin_dir_path(__FILE__) . 'build/index.asset.php';

    wp_enqueue_script(
        'my-block',
        plugin_dir_url(__FILE__) . 'build/index.js',
        $asset['dependencies'],
        $asset['version'],
        wp_rand(),
        true
    );
}
add_action('admin_enqueue_scripts', 'my_enqueue_admin_scripts');

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { registerBlockType } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';

//Settings page
document.addEventListener('DOMContentLoaded', () => {
   const element = document.getElementById('my-block');
   if (typeof element == 'undefined' || element == null) return;
   // * i18n __ here ISN'T translated *
   ReactDOM.render(<SettingsPage/>, element);
})
const SettingsPage = () => {
   return <div>
      {__('Hello world', 'my-block')}
   </div>
}

// Register the block
// ** i18n __ here IS translated **
registerBlockType('my-block/local', {
   title: __('My Block Local', 'my-block'),
   edit: function () {
      return <p> {__('Hello world', 'my-block')} (from the editor)</p>;
   },
   save: function () {
      return <p> {__('Hello world', 'my-block')} (from the frontend) </p>;
   },
});
3
  • Your blocks JS and your settings page JS are not the same and shouldn't be the same. I would expect registerBlockType to never work on a settings page. Likewise your settings pages translations have nothing to do with your block translations and the functions used there, registerBlockType and the associated PHP function are unconnected to anything outside the block editor. What is the purpose of this page though? Normally blocks are configured via the block editor sidebar, not a settings page, and global configuration happens via global styles. This is a very uncommon thing to do
    – Tom J Nowell
    Commented Mar 7, 2023 at 11:27
  • 1
    to be clear, you should not use the same script to implement a block, and to implement JS for a different page such as a settings page/dashboard/frontend JS/etc, they need to be separate independent bundles, even if they share files/packages/code, registerBlockType will never work on your settings page and you can't and shouldn't be running your settings page app bootstrap in your block JS. It needs its own separate entry point and build target, and its own registration/enqueue
    – Tom J Nowell
    Commented Mar 7, 2023 at 11:45
  • The intention is to create a Plugin Setting Page using Reac. But with the possibility of using localization in the React Component, which I have no clue how to get React to use the translations. The block, as you say, has nothing to do with this setting page, I'm just using the same .js file. The settings page just load my_menu_page_template()
    – Jorge
    Commented Mar 7, 2023 at 13:06

1 Answer 1

2

adds an admin menu page with a div that React replaces, but the localization inside this React doesn't work

Actually, since you are enqueueing the same script (build/index.js), which is automatically registered by register_block_type(), then in your my_enqueue_admin_scripts() function, just do wp_enqueue_script( 'my-block-local-editor-script' ) to enqueue/load the script on your admin menu page.

And secondly, change the add_action('enqueue_block_editor_assets', 'script_translations') to add_action('admin_enqueue_scripts', 'script_translations'), i.e. use the admin_enqueue_scripts action instead to set the script translations. That way, the translations would be loaded both on your custom admin page and core admin pages where the block-based editor is used, e.g. the post editing screen at wp-admin/post.php.

However, I suggest you to use a separate JS file for your admin page's (React) code, and manually call wp_set_script_translations() after you enqueued your script, e.g.

$asset = include plugin_dir_path( __FILE__ ) . 'build/settings-page.asset.php';

wp_enqueue_script(
    'my-settings-page',
    plugin_dir_url( __FILE__ ) . 'build/settings-page.js',
    $asset['dependencies'],
    $asset['version'],
    true
);

wp_set_script_translations(
    'my-settings-page', // script handle
    'my-block',         // text domain
    plugin_dir_path( __FILE__ ) . 'languages'
);
  • Note: With the above example, WordPress will try to find the JSON translations file at languages/<text domain>-<locale>-<script handle>.json in your plugin folder, e.g. languages/my-block-es_ES-my-settings-page.json for the Español locale.

    If not found, WordPress will try to find the file at languages/<text domain>-<locale>-<MD5 hash of the relative file path>.json, e.g. languages/my-block-es_ES-3e9997d5fc8385c27402b8531ec46c31.json for the Español locale. ( md5( 'build/settings-page.js' ) equals 3e9997d5fc8385c27402b8531ec46c31 )

  • You can see my scripts here and the above example is the actual code I used in my sample plugin.

2
  • Thanks, I removed all references to the block and the strings are now translated.
    – Jorge
    Commented Mar 8, 2023 at 8:40
  • 1
    Glad it worked for you, but I revised my answer because apparently I pasted the wrong MD5 hash... and then decided to add links to my sample plugin (which I hope helps you more).
    – Sally CJ
    Commented Mar 8, 2023 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.