Skip to content Skip to sidebar

This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- - 9:00 – 18:00 9:00 – 18:00 9:00 – 18:00 9:00 – 18:00 9:00 – 18:00
- - - - - - -

Supporter timezone: America/Lima (GMT-05:00)

Tagged: 

This topic contains 27 replies, has 1 voice.

Last updated by Andreas W. 1 month, 3 weeks ago.

Assisted by: Andreas W..

Author Posts
February 13, 2026 at 1:18 am #17819089

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

The issue is actually not inside the theme; it is inside the Coloron Blocks Plugins.

As the issue only occurs for the Lens Type Block, the issue might be related to the
attributes named description and also name.

In your block.json and block-manifest.php you have for example:

- top-level block metadata: "description": "Coloron Lens Type"

- an attribute ALSO named: "description": { "type": "string" }

That’s a name collision between a reserved/commonly-used block.json property and an attribute key. Many tools (including translation extractors) flatten/merge data structures at some point, and collisions like this can cause exactly what you’re seeing: strings appear in the editor package, but don’t map back correctly to the block attributes when WPML rebuilds the translated post.

Also, name is a risky attribute key because it’s used everywhere as an identifier in block contexts (block “name”, block type “name”, etc.). Not guaranteed to break, but it’s another “collision-prone” key.

Why only Lens Type?
Because your other block (coloron/hero) doesn’t have those attribute keys colliding with metadata keys.

Best fix: rename attributes to non-reserved, unique keys:

- name → lensName

- description → lensDescription (or body, text, etc.)

Example:

"attributes": {
  "imageUrl": { "type": "string" },
  "imageId": { "type": "number" },

  "lensName": { "type": "string", "default": "" },
  "header": { "type": "string", "default": "" },
  "lensDescription": { "type": "string", "default": "" }
}

You would then also need to adapt those attributes inside the index.js file.

February 13, 2026 at 7:54 pm #17821677

lauraR-37

Thank you for the suggestion!

I renamed the attributes tothese:
"lensName": {
"type": "string",
"default": ""
},
"lensHeader": {
"type": "string",
"default": ""
},
"lensDescription": {
"type": "string",
"default": ""
}

All text disappeared in the block editor.
I added the text to the default language then I opened the Advanced Translation Editor. Translations were still there.
I pressed the Save and Complete button.
The attributes are still not translated only the button.

Do you have other suggestion to solve the issue?

February 15, 2026 at 6:12 am #17823067

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

I am suspecting the cause of the issue is the Registration Lifecycle of those Custom Blocks:

Traditional Method:
When you use register_block_type('folder/'), WordPress parses the block.json file. WPML hooks into this event to find your attributes.

Manifest Method:
Your plugin uses wp_register_block_metadata_collection( __DIR__ . '/build', __DIR__ . '/build/blocks-manifest.php' ). This loads a PHP array into memory instantly, bypassing the per-block "parsing" stage that WPML depends on for auto-detection.

It might be that WPML is not yet optimized for this registration method, and I will verify this together with out second tier support team.

Once we havenews for you, I will reach out here again.

February 15, 2026 at 7:24 am #17823104

lauraR-37

Thank you I appreciate that you are checking it for me

February 17, 2026 at 9:38 pm #17830494

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

Reviewing your plugin, it would be expected that the recommended changes have no effect.

When creating Gutenberg blocks, you use:
/src → your editable source code folder
package.json
node.js package manager

Then you build the final blocks at:
/build → compiled output (auto-generated)

If you make changes to the blocks, then this must occur in the /src folder before running "npm run build" again.

Did you do this before updating the plugin?

---

Take note that I created a small custom plugin with two blocks and registered them using the same wp_register_block_metadata_collection() function. I had no issue with translating those blocks on my test.

You can see my test here:
hidden link

February 18, 2026 at 9:40 pm #17833993

lauraR-37

I ran npm run build after I made the changes. That is why I needed to add the text again as the attributes changed. I am unsure how else could I fix this. On other pages the block works and translates well

February 19, 2026 at 11:25 pm #17837277

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

Note that this request is usually out-of-scope for support, as I already created a custom plugin using the same way to register blocks as your plugin, and it works as expected. I can not confirm any unexpected bugs.

The only thing I can offer is to compare both plugins and see if I can identify an issue.

Could you please provide me with FTP/SFTP access so that I can download your plugin from your server? If you could also include the development version as a zip file on the server, it would be really helpful.

The private reply form is enabled again.

March 5, 2026 at 2:30 am #17873481

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

I have downloaded the latest versions of your custom theme and plugin from your server and will test them on a dev site.

March 6, 2026 at 6:34 am #17876593

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

Until now, the issue does not occur on my tests.

I used the "Coloron Lens Type Slider" block with four "Coloron Lens Type Blocks" and it translates as expected.

I will need to run more tests on a copy of your actual site and ask you for more patience.

Captura de pantalla 2026-03-06 013305.png
March 7, 2026 at 12:10 am #17878740

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

I was able to find out that the issue only occurs, of the Slider has an additional block included, like in your example the "Button".

I will keep testing and try to replicate this issue on a dev site.

March 7, 2026 at 12:19 pm #17879266

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

I was able to recreate the issue with a new custom block and found that it is caused by how the block is registered and rendered.

WPML has a compatibility limitation with certain Gutenberg block architectures that combine custom translatable attributes with InnerBlocks, especially when using a hybrid rendering path (part saved in save(), part rendered in PHP). In these cases, WPML can detect the translated attribute, but it may not be reflected correctly on the frontend output.

Workaround:

The safest approach is to avoid mixed serialization/render paths for translatable values.

And most importantly:

Ensure translatable attributes are represented in a single consistent output path.

In practice, this usually means including translatable attributes in save() output, instead of splitting them between save() and PHP rendering.

Static block:

Uses edit() + save()
save() writes frontend markup into post_content
Dynamic block:

Uses edit() + PHP rendering (render_callback / render.php)
Frontend HTML is generated in PHP at runtime

In your specific case, I can confirm that translation issues appear when translatable block attributes are not part of the saved serialization path (save()), while the block also contains InnerBlocks.

Example:
A block containing a Heading and InnerBlocks is hybrid:
- Heading comes from PHP in render.php using $attributes['text'].
- Inner blocks come from serialized JS output via save() => InnerBlocks.Content in index.js.

The solution would be to not render the heading with render.php and make sure it is rendered through JS in index.js using the save() function.

---

I am escalating this issue now internally so that the Second Tier Support can take a closer look.

March 9, 2026 at 8:26 pm #17883268

lauraR-37

Thanks for the updates! I really appreciate looking into this. I feel like we are very close to the solution 🙂

March 10, 2026 at 8:46 am #17884358

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch )

Timezone: America/Lima (GMT-05:00)

I do sadly not yet have any internal feedback on this matter, but this looks more like a limitation in WPML, and I am not sure if there will be a quick fix available.

I will keep you updated once I have feedback from the team.

For now, I would suggest letting you block handle the rendering in index.js while using attributes inside the save() function. Do not render the block in render.php as you will run into issues if the block uses a nested block.

According ot my tests, it should work if you use a static block.

To make lens-type static, remove the server render callback from the block metadata and keep the save() function.

In your plugin, WordPress registers the block from the build directory via coloron-blocks.php, so the relevant change is in build/lens-type/block.json. Delete this line:

"render": "file:./render.php"

After that, the block becomes static because WordPress will use the markup produced by save() in build/lens-type/index.js and stop calling render.php. You can then delete render.php, although it’s just a cleanup.

One important detail: if you normally build from src/, make this change in the source block.json and rebuild; otherwise, the next build will restore the render property. In your provided plugin, I only see the built files, so editing build/lens-type/block.json is the direct fix here. I would need a plugin that includes the /src folder to test this.