0

I have created Gutenberg blocks for my shortcodes, below is some code:

The code in PHP file in init hook to load script:

wp_register_script(
    'my-blocks-script', $pluginurl . '/custom-blocks.js',
    array( 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-editor' ),
    filemtime( $plugindir . '/custom-blocks.js' )
);

// Script contains translations
if( function_exists('wp_set_script_translations') ) {
    wp_set_script_translations( 'my-blocks-script', 'my-text-domain' );
}

// Shortcode block
register_block_type( 'custom-block/my-shortcode', array(
    'editor_script' => 'my-blocks-script'
) );

JS code: file: custom-blocks.js

( function (blocks, editor, components, i18n, element ) {
    // Define common variables
    var el = wp.element.createElement;
    var registerBlockType = wp.blocks.registerBlockType;
    var InnerBlocks = wp.editor.InnerBlocks;
    var BlockControls = wp.editor.BlockControls;
    var Dashicon = wp.components.Dashicon;
    var __ = wp.i18n.__;

    // Shortcode
    registerBlockType( 'custom-block/my-shortcode', {
        title: __( 'Shortcode Title', 'my-text-domain' ),
        description: '',
        icon: Dashicon.cogs,
        category: 'common',
        attributes: {
            display: {
                type: 'boolean',
                default: true
            }
        },
        edit: function() {
            return [
                el( components.CheckboxControl, {
                    label: __( 'Display it?', 'my-text-domain' ),
                    checked: props.attributes.myAttr,
                    onChange: function( val ) {
                        props.setAttributes({ myAttr: val })
                    }
                } ),
            ];
        },
        save: function(props) {
            return(
                el('div', { className: props.className }, '[my-shortcode display="'+props.attributes.display+'"]' )
            );
        }
    } );

} ) (
    window.wp.blocks,
    window.wp.editor,
    window.wp.components,
    window.wp.i18n,
    window.wp.element
);

Everything works fine, blocks display result too. but now I want to translate "Display it?" text with another language ( I use Loco Translate plugin ), I have checked po file the translation string is there, also translated strings in PHP file works fine.

Here, only the JS file transition does not work.

7
  • Do you have var i18n = wp.i18n somewhere in your script or on the page? Because the translation library is wp.i18n.
    – Sally CJ
    Feb 18, 2019 at 10:19
  • @SallyCJ please check I have updated whole JS code. Feb 18, 2019 at 10:43
  • Ok, but there's a syntax error here: el('div', { className: props.className }, '[my-shortcode display='"+props.attributes.display+"']' )
    – Sally CJ
    Feb 18, 2019 at 11:16
  • @SallyCJ Sorry it's by mistake here, but there is no JS error or no issue with functionality. the only issue is translation does not work. Feb 18, 2019 at 11:42
  • Yes, I understand. But even just in the question, you should always avoid typos and syntax errors. It will greatly help others when testing your code. And there's another typo there: edit: function() should be edit: function(props).
    – Sally CJ
    Feb 18, 2019 at 13:56

1 Answer 1

4

only the JS file translation does not work

It's most likely because WordPress couldn't find your translation file, which should be in a valid JED format, like so:

{
  "domain": "my-text-domain",
  "locale_data": {
    "my-text-domain": {
      "": {
        "domain":       "my-text-domain",
        "plural-forms": "n != 1",
        "lang":         "en-us"
      },
      "Shortcode Title": [
        "Shortcode Title translated"
      ],
      "Display it?": [
        "Display it? translated"
      ],
      "Another text 1": [
        "Translated text - singular",
        "Translated text - plural"
      ],
      "Another text 2": [
        "Translated text"
        // No plural.
      ]
    }
  }
}

And saved with a name in this format: ${domain}-${locale}-${handle}.json. For example, in your case, it could be my-text-domain-en_US-my-blocks-script.json if the site's language is English (United States) (see "General Settings" → "Site Language").

And when you call wp_set_script_translations(), you can specify the third parameter ($path) which is the full absolute file path to the directory containing the JS/JSON translation files. E.g.:

// $pluginurl was taken from your code
wp_set_script_translations( 'my-blocks-script', 'my-text-domain', $pluginurl . '/languages' );

Also, you can use po2json to convert PO/.po files to a JED-compatible JavaScript object or JSON string.

Notes:

  • In the above JS/JSON translation data, the locale as in "lang": "{locale}" should be the GlotPress locale as you can see in the table on this page. For example, en-gb for English (UK).

  • In your JS/JSON translation file name, the locale as in ${domain}-${locale}-${handle}.json should be the WP locale as you can see in the table on this page. For example, en_GBfor English (UK).

3
  • 1
    Here, we need to provide translations with fixed languages, isn't a dynamic way? like loco translate scan the PHP ( also an option to scan JS files ) and generate POT file and add translations from the backend? Feb 18, 2019 at 14:25
  • I think the original question has already been answered.. Nonetheless, in reply to that "dynamic way", you could use the pre_load_script_translations or load_script_translations filter - in your callback, you could parse your PO file and generate the JSON translations string, and return the string. You should also check this post.
    – Sally CJ
    Feb 18, 2019 at 17:56
  • Can you please saw any examples, how can I use those filters? Feb 23, 2019 at 12:10

Your Answer

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

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