Skip to content Skip to sidebar

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

Problem:
The client refers to the following documentation. The client is experiencing issues with translating urlencoded shortcode attributes using WPML. The recommended approach and hooks like

wpml_pb_shortcode_encode

and

 wpml_pb_shortcode_decode

are not found in the latest version of WPML, and there is no built-in method to handle urlencoded shortcode attributes gracefully.
Solution:
We explained that the hooks have been customized to handle specific cases, which is why they might not be visible or work as expected in the client's current setup. The original hooks can be found in the file path

\wp-content\plugins\sitepress-multilingual-cms\addons\wpml-page-builders\classes\Shared\st\strategy\shortcode\class-wpml-pb-shortcode-encoding.php

.

If you run into a similar issue, please open a support ticket and assist us in recreating the issue on a test site which we will provide. This way we can escalate such issues to the compatilbity team for further revision.

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 5 replies, has 0 voices.

Last updated by wpexplorer 3 months, 1 week ago.

Assisted by: Andreas W..

Author Posts
April 9, 2025 at 11:10 pm #16916168

wpexplorer

Background of the issue:
I am trying to translate shortcode attributes that use urlencoding with WPML. They end up looking like this: hidden link, which is difficult for an average user to understand. I found this guide: https://wpml.org/documentation/support/translating-urlencoded-shortcodes/, but the recommended approach doesn't work with the latest version of WPML. I couldn't find any references to hooks like wpml_pb_shortcode_encode or wpml_pb_shortcode_decode in the core and string translation plugins. Even if those hooks worked, they wouldn't be a good solution because there's no way to target specific shortcodes. I wonder why WPML doesn’t provide a built-in way to handle this more gracefully, like automatically rendering urlencoded_json attributes in a user-friendly format if marked in the wpml-config.xml file. A simple UI improvement like this (example: hidden link) would help make the content understandable and editable without needing to decode or manually reformat anything.

Symptoms:
The recommended approach for translating urlencoded shortcodes doesn't work with the latest version of WPML. I couldn't find any references to hooks like wpml_pb_shortcode_encode or wpml_pb_shortcode_decode.

Questions:
Why doesn't the recommended approach for translating urlencoded shortcodes work with the latest version of WPML?
Why can't I find references to hooks like wpml_pb_shortcode_encode or wpml_pb_shortcode_decode in the core and string translation plugins?
Why doesn't WPML provide a built-in way to handle urlencoded shortcode attributes more gracefully?

April 10, 2025 at 7:01 am #16916780

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) Spanish (Español ) German (Deutsch )

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

Hello,

Those are custom hooks that need to be saved inside the functions.php file of a Child Theme:

add_filter( 'wpml_pb_shortcode_encode', 'wpml_pb_shortcode_encode_urlencoded_json', 10, 3 );
function wpml_pb_shortcode_encode_urlencoded_json( $string, $encoding, $original_string ) {
    if ( 'urlencoded_json' === $encoding ) {
        $output = array();
        foreach ( $original_string as $combined_key => $value ) {
            $parts = explode( '_', $combined_key );
            $i = array_pop( $parts );
            $key = implode( '_', $parts );
            $output[ $i ][ $key ] = $value;
        }
        $string = urlencode( json_encode( $output ) );
    }
    return $string;
}
 
add_filter( 'wpml_pb_shortcode_decode', 'wpml_pb_shortcode_decode_urlencoded_json', 10, 3 );
function wpml_pb_shortcode_decode_urlencoded_json( $string, $encoding, $original_string ) {
    if ( 'urlencoded_json' === $encoding ) {
        $rows = json_decode( urldecode( $original_string ), true );
        $string = array();
        foreach ( $rows as $i => $row ) {
            foreach ( $row as $key => $value ) {
            if ( in_array( $key, array( 'text', 'title', 'features', 'substring', 'btn_text', 'label', 'value', 'y_values' ) ) ) {
                    $string[ $key . '_' . $i ] = array( 'value' => $value, 'translate' => true );
                } else {
                    $string[ $key . '_' . $i ] = array( 'value' => $value, 'translate' => false );
                }
            }
        }
    }
    return $string;
}

Did you save the functions to the functions.php file?

Best regards
Andreas

April 10, 2025 at 10:25 pm #16920557

wpexplorer

I'm a developer so I understand know how hooks work. And no, it didn't do anything.

I also tried looking for the apply_filters() definition to see how the hooks work and couldn't find anything remotely close to wpml_pb_shortcode_encode or wpml_pb_shortcode_decode in the plugin files - in what file are those hooks supposed to be registered?

The only hook I can find that starts with wpml_pb is "wpml_pb_shortcode_content_for_translation" (again, I checked the main plugin, string translations and even the older page builders plugin)

Can you please have a look at my suggestion though as well. As I mentioned even if these hooks work, they appear to apply globally which is not good as every shortcode works differently. Also if the theme registers these hooks and so does a plugin they can conflict. These hooks need to pass the shortcode tag (name) to the filter.

Plus, it would be best if WPML simply converted encoded strings into an easy to use format for the user.

Thank you.

April 11, 2025 at 2:08 pm #16923061

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) Spanish (Español ) German (Deutsch )

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

As far I am aware those are custom hooks that were created by the compatilbity team only for this given purpose. They are not part of the WPML plugin.

Maybe your XML config is not correct. I can offer to take a look as admin, if you agree?

I would like to request temporary access (wp-admin and FTP) to the website to investigate the issue further.

You can find the required fields below the comments section when you log in to leave the next reply. The information you provide is private, meaning only you and I can see and access it.

IMPORTANT
Please be sure to back up your website and database before granting us access.
If you can't see the "wp-admin / FTP" fields, your post and website credentials will be set to "PUBLIC." DO NOT publish the data unless you see the required wp-admin / FTP fields.

The private reply form looks like this:
hidden link

Click "I still need assistance" the next time you reply.

Video:
hidden link

Please note that we are required to request this information individually on each ticket. We are not permitted to access any credentials that were not specifically submitted on this ticket using the private response form.

April 14, 2025 at 4:30 am #16927177

wpexplorer

Can you please forward this thread to a developer. Thank you!

"As far I am aware those are custom hooks that were created by the compatibly team only for this given purpose. They are not part of the WPML plugin."

How could a hook possibly work if doesn't even exist in the plugin? Hooks must be registered via apply_filters to do anything at all.

I can't provide access, because this is something I'm working on locally via MAMP PRO

I would also like my recommendation forwarded to the appropriate team - thank you!

April 15, 2025 at 9:41 am #16932843

Andreas W.
WPML Supporter since 12/2018

Languages: English (English ) Spanish (Español ) German (Deutsch )

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

I means with this, that the provided hooks have been customized as otherwise WPML will not be able to handle the translation ins some cases.

You can find the original hooks for example at:

\wp-content\plugins\sitepress-multilingual-cms\addons\wpml-page-builders\classes\Shared\st\strategy\shortcode\class-wpml-pb-shortcode-encoding.php

public function encode( $string, $encoding ) {
		$decoded_string = $string;
		switch ( $encoding ) {
			case self::ENCODE_TYPES_BASE64:
				$string = base64_encode( $string );
				break;

			case self::ENCODE_TYPES_VISUAL_COMPOSER_LINK:
				$output = '';
				if ( is_array( $string ) ) {
					foreach ( $string as $key => $value ) {
						$output .= $key . ':' . rawurlencode( $value ) . '|';
					}
				}
				$string = $output;
				break;

			case self::ENCODE_TYPES_ENFOLD_LINK:
				$link = explode( ',', $string, 2 );
				if ( $link[0] !== 'lightbox' ) {
					$string = 'manually,' . $string;
				}
				break;

		}

		return apply_filters( 'wpml_pb_shortcode_encode', $string, $encoding, $decoded_string );
	}

Since this approach works for some plugins or widgets, it might not work for others and this is why our compatilbity team provided a customized version of this hook.

---

I can only escalate an issue internally if it can be replicated. If you can not provide access, I can offer a WPML test site on which you can try to reproduce the problem.

Further, the issue could be, that your XML config is not correct, and I can only revise this, if you can provide me the respective data. I need to know the structure of the original shortcode and your XML config.

April 15, 2025 at 8:21 pm #16936059

wpexplorer

Oh my, I was searching the "wpml-translation-management" plugin which is why I couldn't find the filter. I don't know why I thought that was the core plugin...

Now, I can dig through the code and see how it works and figure out what's wrong.

Nevertheless, it would be a good idea for WPML to automatically format any encoded string into an easy to use format, without having to divide it up into separate 'chunks".