Skip Navigation

This thread is resolved. Here is a description of the problem and solution.

Problem:
You need to translate scripts within a post, such as iframes or shortcodes, for different languages. However, when using the Advanced Translation Editor (ATE), you encounter issues where the original language script appears blank and modifications in the new language do not save correctly. After editing and saving the post, scripts revert back to the original language.
Solution:
We recommend not using the ATE for pages that contain scripts you need to translate. Instead, use a different method to manage translations for these specific pages to avoid the issues you're experiencing. For detailed guidance on how to implement this, please refer to our documentation on using different translation editors for different pages: Using Different Translation Editors for Different Pages.

If this solution does not apply to your case, or if it seems outdated, we highly recommend checking related known issues at https://wpml.org/known-issues/, verifying the version of the permanent fix, and confirming that you have installed the latest versions of themes and plugins. Should you need further assistance, please do not hesitate to open a new support ticket at WPML support forum.

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.

This topic contains 36 replies, has 2 voices.

Last updated by Bruno Kos 4 months, 2 weeks ago.

Assisted by: Bruno Kos.

Author Posts
June 29, 2024 at 11:41 am #15857715

justinK-16

Background of the issue:
I would like to be able to translate scripts within a post. I have a widget displaying iframes or shortcodes and need to modify these codes for different languages. The site I need help with is hidden link.

Symptoms:
Empty fields appear in the ATE; the original language script is blank in the ATE, and I cannot add the modified script to the New Language field in the ATE. If I edit the script by either editing the post with Elementor in the new language and updating the script, or editing the script in String Translation, the elements display as per the updated code. However, the next time the post is edited and saved in the ATE, all scripts revert back to the original language script/code. Upon checking the String Translation for the scripts, they too have reverted to the original code.

Questions:
How do we translate scripts?

July 1, 2024 at 5:42 am #15865525

Bruno Kos
Supporter

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+01:00)

Hi,

Thank you for contacting WPML support!

Scripts and coded are typically omitted from the translation editor as translating these either automatically or through human translation can lead to broken sites and errors if the code is translated improperly.

That's why for the pages where you have codes to be translated we recommend this:
https://wpml.org/documentation/translating-your-contents/using-different-translation-editors-for-different-pages/#how-to-get-different-designs-for-different-translations

Regards,
Bruno Kos

July 1, 2024 at 7:04 am #15866089

justinK-16

Hi Bruno

Thanks for following up.

Is there any way to add these scripts to the ATE?

Considering the fields are showing but empty - is there a way to activate/populate them for translation?
If they are for a standard element we have created and wish to use repeatedly on other posts, can we register the script (maybe a XML registration)?
Although the script would be unique on all new posts (most not all).

Here is the sample code:

<script async src="hidden link" charset="utf-8"></script>

If you have any options or ideas on how to speed up/streamline translations by translating in the ATE would be appreciated.

July 1, 2024 at 7:29 am #15866193

Bruno Kos
Supporter

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+01:00)

Would you be willing to provide me with WordPress credentials so I could investigate the issue directly?

And send me the URL of the page where such code is added so I could have a look on how this is added there.

https://wpml.org/purchase/support-policy/privacy-and-security-when-providing-debug-information-for-support/

I marked your next reply as private so that you can safely add credentials.

July 1, 2024 at 2:48 pm #15869368

Bruno Kos
Supporter

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+01:00)

If you try creating XML for the HTML widget like this:
https://wpml.org/documentation/related-projects/wpml-compatibility-test-tools-plugin/registering-custom-elementor-widgets-for-translation/, this would apply to all the pages where such element is used.

That is why we suggest manual translation mode.

But if you only need to translate the URL, what about this - see image.

It is about this approach:
https://wpml.org/forums/topic/elementor-html-widget-content-does-not-appear-in-advanced-translation/#post-13890085

Clipboard_07-01-2024_012.jpg
July 2, 2024 at 1:12 pm #15875510

justinK-16

Hi Bruno

Just before we go any further with XML registration...

I have tried switching to Manual Translation in the WP editor and also Edit with Elementor and editing the code in the post AND also tried switching to the Classic editor.

All works well and translates UNTIL I switch back to the ATE and make a save - then they revert to the original code.

So these options don't really work for us (I really don't want to leave the posts in the Classic or Manual modes as it will take so long to perform future post updates).

So therefore I am would like to try the XML option but just wish to confirm a couple things first:

1. So are you saying that if we create XML and register it for the Elementor HTML widget it will make the Elementor HTML widget fields translatable for ALL pages/posts when using the ATE?

2. When following the tutorial you supplied for registering Custom Elementor Elements:

HTML widget is not showing under elements that don't have translation settings, but only in the debug portion.
So, as the fields already display in the ATE but are un-editable - could this mean some settings for this widget are already within WPML?

If so, can we access and edit settings somewhere in WPML?
Or otherwise, how do we continue when the Element is not showing as an Element without translation settings?

Sorry for the long explanation but this is very important to us and I would like to get it right - I feel like we have exhausted all options apart from XML at this point.

Thanks again

July 2, 2024 at 1:25 pm #15875710

justinK-16

Sorry one more thing to add.

When testing in the ATE I accidentally added a URL to the script field...

It has been saved to Translation Memory and this has now populated to all the widgets.

I have been looking online as to how to Remove it from Translation memory but I can't find anything current and info from up to 2 years ago say that there currently was no feature but WPML were working on it - is it available now?

Is there a way I can delete this?

Thanks

July 3, 2024 at 8:29 am #15882315

Bruno Kos
Supporter

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+01:00)

"All works well and translates UNTIL I switch back to the ATE and make a save - then they revert to the original code."

This is expected, have a look:
https://wpml.org/faq/why-arent-my-translations-showing/#what-should-i-do-if-ive-mixed-translation-methods-for-posts-or-pages-and-lost-my-translations

So once you disable translation editor for a certain page/post/template you should not open in ATE again. Otherwise ATE will overwrite these fields - fields that don't show up in ATE these are.

There is no option to modify translation memory entries, but you can create glossary items:
https://wpml.org/documentation/translating-your-contents/advanced-translation-editor/how-to-create-and-manage-glossary-entries/#how-to-create-glossary-entries

As for XML I see that even with this:

<wpml-config>
  <elementor-widgets>
    <widget name="html">
      <fields>
        <field>content_width</field>
        <field>html</field>
      </fields>
    </widget>
  </elementor-widgets>
</wpml-config>

It would not show in ATE as ATe itself would not allow it. It would allow only certain elements from the code itself such as URLs or attributes. There is a filter wpml_tm_job_field_is_translatable though but it only allows for translating IDs: https://wpml.org/forums/topic/core-html-block-with-shortcode-not-translateable/#post-14307023

July 3, 2024 at 10:47 am #15883317

justinK-16

Hi Bruno

Thanks for the Glossary Info - helpful:)

You mentioned this earlier:
But if you only need to translate the URL, what about this - see image.
It is about this approach:
https://wpml.org/forums/topic/elementor-html-widget-content-does-not-appear-in-advanced-translation/#post-13890085

Clipboard_07-01-2024_012.jpg

If I could have just the URL appear for translation - Just like the Pinterest URL does - then that is all I am after.

I have attached examples of the Scripts, of which ALL of them contain URLs but so far only the Pinterest URL appears (it is different in that it is within an iframe).

I only want to change the language designator highlighted in yellow within the URL.

I'm not sure I personally 100% understand the filter and the ID option.

Maybe you could tell me if it would work to solve the issue?

Thank you

WPML.jpg
July 3, 2024 at 12:22 pm #15884118

Bruno Kos
Supporter

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+01:00)

I see, so anything within the script will not show in ATE, including URLs? This is because ATE would not parse script element so you can't translate it like that.

Can you check this?
https://wpml.org/forums/topic/translate-html-code/#post-12729093

I believe this client had the same case.

July 3, 2024 at 1:14 pm #15884645

justinK-16

This is interesting...I can see that it would work for a script that I want repeatedly displayed on the same and/or different posts (as long as the shortcode is added in place of the HTML).

However, we have 100's of DIFFERENT widget scripts translating into 5 languages (within the next 2-3 months it may even reach 1000...

If I understand correctly this means each script would need it's own shortcode (and therefore code added to functions.php

Am I correct in thinking this?

July 4, 2024 at 7:03 am #15889505

Bruno Kos
Supporter

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+01:00)

I am not sure of this as translating scripts is typically rare, let alone having thousands of them all across the website. So perhaps you can consider trying a few different approaches ( about from shortcodes and translating these templates manually in WordPress) to see which one will be most convenient for you to handle.

To manage the vast number of widget scripts in different languages without cluttering your `functions.php` file with numerous shortcodes, you can also consider the following:

### Custom Post Types with Meta Fields

Create a custom post type to store each script along with its metadata (e.g., language, widget ID). You can then fetch and display these scripts dynamically using a single shortcode or template function.

#### Steps:
1. **Register a Custom Post Type:**

    function register_widget_scripts_cpt() {
        register_post_type('widget_script', array(
            'labels' => array(
                'name' => __('Widget Scripts'),
                'singular_name' => __('Widget Script')
            ),
            'public' => true,
            'has_archive' => false,
            'supports' => array('title', 'editor'),
        ));
    }
    add_action('init', 'register_widget_scripts_cpt');

2. **Add Meta Fields:**
Use a plugin like Advanced Custom Fields (ACF) to add meta fields for language and any other relevant data.

3. **Fetch and Display the Scripts:**

    function display_widget_script($atts) {
        $atts = shortcode_atts(array(
            'id' => '',
            'language' => 'en',
        ), $atts, 'widget_script');

        if (empty($atts['id'])) {
            return '';
        }

        $args = array(
            'post_type' => 'widget_script',
            'meta_query' => array(
                array(
                    'key' => 'widget_id',
                    'value' => $atts['id'],
                ),
                array(
                    'key' => 'language',
                    'value' => $atts['language'],
                ),
            ),
        );

        $query = new WP_Query($args);
        if ($query->have_posts()) {
            $query->the_post();
            $script = get_the_content();
            wp_reset_postdata();
            return $script;
        } else {
            return 'Script not found';
        }
    }
    add_shortcode('widget_script', 'display_widget_script');

You can also try a single shortcode with a centralized function to handle the retrieval of scripts. This way, you can store your scripts in a single file or an array within your theme or plugin.

### Using a PHP Array for Scripts

1. **Define your scripts in an array:**
Create an array in your theme or plugin's `functions.php` file to store your scripts.

    function get_widget_scripts() {
        return array(
            'widget1_en' => '<script>/* English script for widget1 */</script>',
            'widget1_fr' => '<script>/* French script for widget1 */</script>',
            'widget2_en' => '<script>/* English script for widget2 */</script>',
            'widget2_fr' => '<script>/* French script for widget2 */</script>',
            // Add more scripts here
        );
    }

2. **Create a shortcode to display the scripts:**

    function display_widget_script($atts) {
        $atts = shortcode_atts(array(
            'id' => '',
            'language' => 'en',
        ), $atts, 'widget_script');

        if (empty($atts['id'])) {
            return '';
        }

        $scripts = get_widget_scripts();
        $key = $atts['id'] . '_' . $atts['language'];
        
        if (isset($scripts[$key])) {
            return $scripts[$key];
        } else {
            return 'Script not found';
        }
    }
    add_shortcode('widget_script', 'display_widget_script');

3. **Use the shortcode in your posts or pages:**
Add the shortcode where you want to display the script.

    [widget_script id="widget1" language="en"]

### Explanation
- **Step 1:** You define an associative array with keys combining the widget ID and language. This keeps all your scripts centralized in one place.
- **Step 2:** You create a shortcode function that retrieves the appropriate script from the array based on the `id` and `language` attributes.
- **Step 3:** Use the shortcode in your posts or pages to dynamically display the scripts.

Please note that I have not tested any of the above solutions, these are just ideas as such requirements fall out of the support scope. Perhaps you can check with our https://wpml.org/contractors/ about more ideas as well.

July 4, 2024 at 10:51 am #15891352

justinK-16

Hi Bruno

Thanks for all the options. I have just had our developer look at this and he thinks it is very complicated and a lot of management.

I think we have exhausted all options and switching to manual translation is the only option for now.

It just means every time we want to make an update to a post we need to switch back to ATE - (lose all script language designator changes) - edit posts in all languages - then switch to manual again and update all scripts.

To me this just seems like such a waste of time - do you know if there are any future plans to allow script translations?

Also, it seems now that something has accidentally been saved in the script field - it is populating in EVERY script field and translating that to new languages. Even though the scripts are different obviously the ATE is only recognizing <Script> and translating that from translation memory.

Now you can't leave a field empty - ATE won't let you save.

And I can't add anything otherwise it will populate in the HTML field - instead of the original script.

This is getting very frustrating. You say there are not many websites with lots of scripts out there but THERE ACTUALLY ARE MANY TRAVEL BOGS displaying multiple and different activity widgets containing different scripts in different languages.

Are there any other options that can be sourced - maybe from the development team?

Thanks again

July 4, 2024 at 11:04 am #15891418

justinK-16

By the way - i did not try this as it is only suitable for 1 widget that would get reused. (and we have too many).

But regarding shortcodes:

I created a shortcode of the script in both EN and IT (2 SC's).

Added the EN shortcode in place of the HTML widget

Translate the shortcode String

However, it too reverts to the original shortcode upon saving in the ATE. ALso changes the string shortcode back to the EN version...

Is there something that may solve this and possibly achieve the end result?

July 4, 2024 at 11:08 am #15891419

justinK-16

When i said I did not try this, I meant this suggestion:

1. Add the following code to the theme's functions.php file to register the shortcode for this widget:

add_shortcode('custom_oa_widget', function(){
$lang = apply_filters( 'wpml_current_language', null );
$content = '<div id="oa_widget" class="widget-js"></div>';

if ($lang == 'en') {
//Put the URL for EN here
$script_src = '<u>hidden link</u>';
} else {
//Default URL.
$script_src = '<u>hidden link</u>';
}

$content .= '<script type="text/javascript" src="'.$script_src.'"></script>';
return $content;
});

Please make sure to replace the URL for English in the above snippet with the new URL you want to use

2. Remove the HTML code you use from the original page content

3. Add the following shortcode in the original page content instead of the HTML code:

1
[custom_oa_widget]
This will change the link in your widget according to the page language.

Let me know please if that helps.