- ステータス
- 開発者からの返答待ち
- 関連するプラグイン/テーマ
- Pro
- トピックタグ
- Compatibility
問題の概要
WPMLでProテーマを使用する場合、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‘などのキーを追加するため)。