Followup on previous topic - Part #2

Hi,

I do have un update on Followup on previous topic!

WPML support was very persisting this time, and ended up with providing custom code that makes it possible to translate content on a Single Layout. The codes is not (yet) perfect, as it doesn’t recognise content that’s nested inside an elements, such as text strings in a counter-element. Is that something you guys could chip in? It would be great to see the compatibility between ThemeCo and WPML increase again, and I hope sharing this, helps a bit. But it would be great if your developers would add their bit as well!

/**
 * WPML Workaround for compsupp-8255 
 */
 
// 1. Register strings when saving Layout posts.
  
add_action( 'save_post', function( $post_id, $post, $update ) {
 
    if ( wp_is_post_revision( $post_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) ) {
        return;
    }
 
    $pt = get_post_type( $post_id );
    $layout_types = [ 'cs_layout_single', 'cs_layout_archive', 'cs_layout_single_wc', 'cs_layout_archive_wc' ];
 
    // If the site uses other cs_layout_* types, widen this check:
    // if ( strpos( $pt, 'cs_layout_' ) !== 0 ) return;
    if ( ! in_array( $pt, $layout_types, true ) ) {
        return;
    }
 
    // Only if WPML String Translation is present.
    if ( ! has_action( 'wpml_register_single_string' ) ) {
        return;
    }
 
    $data = json_decode( (string) $post->post_content, true );
    if ( ! is_array( $data ) ) {
        return;
    }
 
    $items   = cs_wpml_cs_collect_text_content( $data ); // [ path => original_text ]
    $context = 'cornerstone-layout';
 
    foreach ( $items as $path => $original ) {
        // Includes a short hash to avoid collisions and keep it semi-readable in ST.
        $hash = substr( md5( $path . '|' . $original ), 0, 10 );
        $name = $path . ' #' . $hash;
 
        do_action( 'wpml_register_single_string', $context, $name, $original );
    }
 
}, 10, 3 );
 
 
// 2. Replace strings on load for Layout documents.
 
add_filter( 'cs_layout_load_content', function( $post_content ) {
 
    if ( ! has_filter( 'wpml_translate_single_string' ) ) {
        return $post_content;
    }
 
    $data = json_decode( (string) $post_content, true );
    if ( ! is_array( $data ) ) {
        return $post_content;
    }
 
    $context = 'cornerstone-layout';
 
    $data = cs_wpml_cs_translate_text_content( $data, $context );
 
    return wp_json_encode( $data );
 
}, 10, 1 );
 
 
// Collect ONLY 'text_content' strings
 
function cs_wpml_cs_collect_text_content( array $data ) : array {
    $out = [];
 
    $walk = function( $node, $path ) use ( &$walk, &$out ) {
 
        if ( is_array( $node ) ) {
            foreach ( $node as $k => $v ) {
 
                $new_path = ( $path === '' ) ? (string) $k : $path . '.' . $k;
 
                if ( $k === 'text_content' && is_string( $v ) ) {
                    // Skip Dynamic Content tokens like {{dc:...}} or {{ acf... }}
                    if ( strpos( $v, '{{' ) === false ) {
                        $out[ $new_path ] = $v;
                    }
                    continue;
                }
 
                if ( is_array( $v ) ) {
                    $walk( $v, $new_path );
                }
            }
        }
    };
 
    $walk( $data, '' );
    return $out;
}
 
 
/**
 * Translate ONLY 'text_content' strings.
 */
function cs_wpml_cs_translate_text_content( array $data, string $context ) : array {
 
    $walk = function( $node, $path ) use ( &$walk, $context ) {
 
        if ( is_array( $node ) ) {
            foreach ( $node as $k => $v ) {
 
                $new_path = ( $path === '' ) ? (string) $k : $path . '.' . $k;
 
                if ( $k === 'text_content' && is_string( $v ) ) {
 
                    // Skip Dynamic Content tokens like {{...}}
                    if ( strpos( $v, '{{' ) === false ) {
 
                        $hash = substr( md5( $new_path . '|' . $v ), 0, 10 );
                        $name = $new_path . ' #' . $hash;
 
                        $node[ $k ] = apply_filters( 'wpml_translate_single_string', $v, $context, $name );
                    }
 
                    continue;
                }
 
                if ( is_array( $v ) ) {
                    $node[ $k ] = $walk( $v, $new_path );
                }
            }
        }
 
        return $node;
    };
 
    return $walk( $data, '' );
}

-Resave your single layout in the Cornerstone editor

-Go to WPML > String Translation and look for the domain “cornerstone-layout”

-If needed, select the strings and change their language to Dutch

-Translate them

-Go to “Cornerstone > Settings” and clear cache.