Learn how to specify which custom Gutenberg blocks you developed should be translatable. You can do this by configuring the wpml-config.xml file with the help of the Multilingual Tools test plugin.
This guide is for developers who create their own custom blocks for Gutenberg. If you’re not a plugin author, see how to translate content created with the Gutenberg editor.
Getting Started
To get started, install and activate:
- WPML Core plugin
- WPML String Translation
- Multilingual Tools
The Multilingual Tools plugin shouldn’t be used on live or production sites. Only use it for testing.
Generating and Testing XML Code To Register Gutenberg Blocks For Translation
1. Create a new post or page and add Gutenberg blocks you want to register. Make sure to add test content in every field you want to make translatable, and then publish.
Scroll down to the WPML: Gutenberg Blocks section and copy the generated XML code.
Important: The automatically generated XML code shouldn’t be used as is. You must test and edit it before making it available to your users. See the next step.
2. Go to WPML → Settings and paste the generated XML under the Custom XML Configuration tab.
Make sure to review the automatically generated code thoroughly. You may need to remove some fields that aren’t meant to be translated, such as configuration fields with specific values.
Save when you’re ready.
3. Go back to the page you published and make small updates, like editing a button’s text or a heading.
Click the plus icon under the Language section to open the Advanced Translation Editor. The fields from the Gutenberg blocks appear in the editor and are available for translation.
Once you’ve registered the Gutenberg blocks you want to make translatable, you can create your language configuration file. If you already have one, just edit it to add your finalized XML code.
Examples of Registering Gutenberg Blocks as Translatable
Translating Images
Let’s say that you have an image that is shown using the following code:
<!-- wp:image {"id":3} --> <figure class="wp-block-image"><img src="http://example.com/wp-content/uploads/2018/07/figure-2.png" alt="Image alt text" class="wp-image-3"/><figcaption>Image Caption</figcaption></figure> <!-- /wp:image -->
You want to translate the figcaption
and the alt
attribute values of this image.
To achieve this, you need to insert the following code into wpml-config.xml:
<wpml-config> <gutenberg-blocks> <gutenberg-block type="core/image" translate="1"> <xpath>//figure/figcaption</xpath> <xpath>//figure/img/@alt</xpath> </gutenberg-block> </gutenberg-blocks> </wpml-config>
Please bear in mind that the type is core/image
and not wp:image
since this is the value returned by the block API.
Translating Links
You can specify which Gutenberg block fields are links. WPML will then replace any links with their translations if they are available.
<wpml-config> <gutenberg-blocks> <gutenberg-block type="core/some-block" translate="1"> <xpath type="link">//a/@href</xpath> </gutenberg-block> </gutenberg-blocks> </wpml-config>
Translation of Block Attributes
Here is one example of a format for the definition of an editor block:
<wpml-config> <gutenberg-blocks> <gutenberg-block type="my-plugin/my-block" translate="1"> <xpath label="My Block">//p</xpath> <key name="title" /> <key name="foo"> <key name="bar1" /> <key name="bar2" /> </key> <key name="/^[^_]\S+$/" search-method="regex" /> <key name="something" search-method="wildcards" /> </gutenberg-block> </gutenberg-blocks> </wpml-config>
You can use the key element in the same way as it is used with the Admin texts / wp_options configuration. This also means that you can have key elements inside parent key elements.
You can use the label attribute to add optional custom labels that display in the Advanced Translation Editor next to the block elements. When the label attribute is part of the gutenberg-block tag, it will be used as a fallback label for elements of the block that don’t have a specific label defined.
<wpml-config> <gutenberg-blocks> <gutenberg-block type="my-plugin/mybutton" translate="1" label="My fallback block label"> <xpath>//span</xpath> <xpath>//a@href</xpath> </gutenberg-block> </gutenberg-blocks> </wpml-config>
The attribute search-method can have one of two values:
- wildcards (default)
- regex.
You can use wildcards in the same way as for admin texts. This means that an asterisk (*) can be used in the name attribute. Here is an example of one block:
<!-- wp:my-plugin/my-block { "myp": { "mypTitle":"The title", "mypContent":"The Content", "_mypSystem:"Meta attribute to not translate" } } /-->
You can set the block definition using a wildcard:
<wpml-config> <gutenberg-blocks> <gutenberg-block type="my-plugin/my-block" translate="1"> <key name="myp"> <key name="myp*" /> </key> </gutenberg-block> </gutenberg-blocks> </wpml-config>
This will allow you to translate “The title” and “The content” since these are the only attributes starting with myp.
The regex allows you to have a regular expression in the name attribute. This can be extremely useful for complex configurations. Here is an example of one block:
<!-- wp:my-plugin/my-block { "data": { "title":"The title", "_title":"e980759463943209f6f1ae09a239e353", "content":"The Content", "_content":"1502a7b825dfe7b789c63830609f1701" } } /-->
You can set the block definition with a regular expression:
<wpml-config> <gutenberg-blocks> <gutenberg-block type="my-plugin/my-block" translate="1"> <key name="data"> <key name="/^[^_]\S+$/" search-method="regex" /> </key> </gutenberg-block> </gutenberg-blocks> </wpml-config>
This will allow you to translate “The title” and “The content” since these are the only attributes not starting with underscore (_).
Some block plugins save data in a URL-encoded JSON string inside a block’s attribute. The encoding attribute allows you to decode the string and register its subkeys for translation.
For example, the LazyBlocks plugin stores repeater field content in an encoded JSON string:
<!-- wp:lazyblock/testwpml {"name":"%5B%7B%22firstname%22:%22Shekhare%22,%22lastname%22:%22Bhandari%22%7D,%7B%22firstname%22:%22Compatibility%22,%22lastname%22:%22Escalation%22%7D%5D","blockId":"Z169b0O","blockUniqueClass":"lazyblock-testwpml-Z169b0O"} /-->
You can register the firstname and lastname subkeys using the following XML configuration:
<wpml-config> <gutenberg-blocks> <gutenberg-block type="lazyblock/team" translate="1"> <key name="name" encoding="json"> <key name="*"> <key name="firstname" /> <key name="lastname" /> </key> </key> </gutenberg-block> </gutenberg-blocks> </wpml-config>
Translating Block Attribute Links
To enable WPML to automatically translate URLs, you can declare Gutenberg block attributes as links.
Here’s an example of a custom Gutenberg block with a clickable link:
<!-- wp:foo/link {"label":"Click here!","url":"https://example.com/some-page/"} /-->
To make the label and url attributes translatable, add the following to your wpml-config.xml file:
<gutenberg-block type="foo/link" translate="1">
<key name="label" />
<key name="url" type="link" />
</gutenberg-block>
In this configuration, specifying type=”link” for the url attribute enables WPML to automatically translate the URL.
Block Namespace
You can have a global configuration for the block namespace.
Block name is no longer a required part of the definition.
If the block configuration is the same for all blocks in a namespace you can write it like this:
<wpml-config> <gutenberg-blocks> <gutenberg-block type="my-plugin" translate="1"> <key name="data"> <key name="/^[^_]\S+$/" search-method="regex" /> </key> </gutenberg-block> </gutenberg-blocks> </wpml-config>
Automatically Converting IDs in Blocks
The ID conversion is versatile and tries to adapt to most possible formats of IDs (single ID, list of IDs, serialized array, JSON encoded array).
Consider the following block:
<!-- wp:foo/form {"ids":[27,28]} --> <div class="wp-block-foo-form-wrap"> <form class="foo-form" action="" method="post"> <input type="hidden" name="foo_form_post_ids" value="27,28" /> <input type="submit" /> </form> </div> <!-- /wp:foo/form -->
You can declare, as post IDs, the block attribute IDs and the HTML tag attribute value foo_form_post_ids as below:
<gutenberg-block type="foo/form" translate="0"> <key name="ids"> <key name="*" type="post-ids" sub-type="post" /> </key> <xpath type="post-ids" sub-type="post">//*[@name="foo_form_post_ids"]/@value</xpath> </gutenberg-block>
The block will be converted with the highest priority on the filter render_block_data as below:
<!-- wp:foo/form {"ids":[42,43]} --> <div class="wp-block-foo-form-wrap"> <form class="foo-form" action="" method="post"> <input type="hidden" name="foo_form_post_ids" value="42,43" /> <input type="submit" /> </form> </div> <!-- /wp:foo/form -→
You can use the following config attributes:
- type – can be post-ids or taxonomy-ids
- sub-type (optional): can be the specific entity of the type if it’s already known. For instance, product for the Product custom post type. If not defined, the specific entity will be guessed.
Additional Resources
To learn more about the wpml-config.xml file, visit the Language Configuration Files guide.
For customizing other elements using the wpml-config.xml file, visit our additional guides:
- Translate Custom Shortcodes with WPML
- Register Page Builder Content for Translation
- Register Custom Page Builder Widgets for Translation
- Set Translation Options for Custom Fields Using WPML Configuration File
- Register Custom Terms, Types & Taxonomies as Translatable
- Translate Texts that Theme and Plugins Save in wp_options
- Customize WPML Language Switcher Using WPML Configuration File