WPML
Статус
Ожидается ответ автора
Связанный плагин/тема
Pro
Теги темы
Compatibility

Обзор проблемы

При использовании темы оформления Pro с WPML шаблоны макетов, такие как макеты отдельных записей и архивов, созданные в конструкторе Cornerstone, не переводятся с помощью Редактора переводов WPML. Это связано с тем, как Cornerstone обрабатывает рендеринг макетов, что отличается от стандартных типов записей.

Обходное решение

Вариант 1 — Переведите Ваши шаблоны вручную

Используйте встроенный переключатель переводов Cornerstone в верхней части редактора Cornerstone. Это позволит Вам дублировать макет на дополнительный язык и перевести его вручную.

  • Отредактируйте Ваш макет с помощью Cornerstone Builder.
  • В верхней части интерфейса конструктора найдите переключатель языков.
  • Выберите язык, на который Вы хотите перевести.
  • Вручную введите переведённый текст в редакторе макета.

Источник: https://theme.co/forum/t/not-possible-is-it-possible-to-translate-wc-single-layouts-with-wpml/112916/7

Вариант 2 — Пользовательский код в functions.php


Пожалуйста, перед продолжением убедитесь, что у Вас есть полная резервная копия Вашего сайта.

  • Добавьте следующий код в файл functions.php Вашей темы оформления.
    /**
     * 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 );
    	$post = get_post( $post_id );
    	$slug = $post->post_name;
    
    	$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-' . $slug;
    
    	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-' . $slug;
    
    	$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 ( in_array( $k, [ 'text_content', 'counter_before_content', 'counter_after_content' ], true ) && 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 ( in_array( $k, [ 'text_content', 'counter_before_content', 'counter_after_content' ], true ) && 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, '' );
    }
            

  • Пересохраните Ваш макет в редакторе Cornerstone.
  • Перейдите в WPML → Перевод строк и найдите домен cornerstone-layout.
  • Переведите строки.
  • Перейдите в Cornerstone → Настройки и очистите кеш.
Примечание:
В зависимости от виджетов, используемых в Вашем макете, Вам может потребоваться расширить список ключей в обеих функциях 'cs_wpml_cs_collect_text_content' и 'cs_wpml_cs_translate_text_content' (чтобы добавить такие ключи, как «toggle_anchor_text_primary_content», «card_front_text_content», «card_back_text_content» и т. д.).

Все известные проблемы →