Some themes and plugins use urlencoded shortcodes. For example, this is the case with WPBakery Page Builder modules like Progress Bar, Round Chart or Line Chart. In this guide, we explain how to enable the translation of content used with these types of shortcodes.

What are “urlencoded” shortcodes?

When you insert an element that uses urlencoded shortcodes and switch your WordPress editor to Text mode, you will see they look similar to the following.

[vc_progress_bar values="%5B%7B%22label%22%3A%22Development%20Test%22%2C%22value%22%3A%2290%22%7D%2C%7B%22label%22%3A%22Design%20Test%22%2C%22value%22%3A%2280%22%7D%2C%7B%22label%22%3A%22Marketing%22%2C%22value%22%3A%2270%22%2C%22color%22%3A%22bar_blue%22%7D%5D" title="Progress Bar Title Test" units="%"]

The value in such shortcodes is decoded into a JSON encoded array similar to the following:

[{"label":"Development Test","value":"90"},{"label":"Design Test","value":"80"},{"label":"Marketing","value":"70","color":"bar_blue"}]

And finally, that JSON output is also decoded into an array similar to this:

Decoded JSON array
array (
  0 => 
  array (
    'label' => 'Development Test',
    'value' => '90',
  1 => 
  array (
    'label' => 'Design Test',
    'value' => '80',
  2 => 
  array (
    'label' => 'Marketing',
    'value' => '70',
    'color' => 'bar_blue',

If you find this is too complex, don’t worry. This is an internal process where you as an user do not need to intervene.

Translating values in “urlencoded” shortcodes

Now, let us see how to translate the label and value parts of that array. Before WPML 3.9 version, it was difficult to translate shortcodes of this type but now it can be done in few simple steps.

1. Add the shortcode to your wpml-config.xml file.

If you do not have one or you are not familiar with it, this documentation page should help, especially the Page builder content section.

In your wpml-config.xml, besides the regular code that you add for a shortcode, you also need to add the type=”area” and encoding=”urlencoded_json” attributes:

Progress bar shortcode
        <attribute encoding="allow_html_tags">title</attribute>
        <attribute type="area" encoding="urlencoded_json">values</attribute>

2. Add the following code to your theme’s functions.php file.

Progress bar function
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;

The most important part of the above code is located on the following line:

if ( in_array( $key, array( 'text', 'title', 'features', 'substring', 'btn_text', 'label', 'value', 'y_values' ) ) )

Here, you must add the correct keys which you can get from the decoded JSON array. In our example, they would be label and value.

And that’s it! Now, in the Translation Editor, you will see the label and value fields from those shortcodes and they will be ready for translation.

Translation Editor: "label" and "value" available for translation
Translation Editor: “label” and “value” available for translation