ShortcoderがWPML多言語対応してくれない
shortcoderはなにも考えずにさまざまなコードをショートコード化してくれるめちゃくちゃべんりなプラグインで愛用しています。サイト上のカテゴライズが不完全な場合でもとりあえずショートコード化して突っ込んでおけばあとから固定ページ内や自作テンプレート内を探すこともなくなるのでめちゃくちゃオススメなのですが、多言語で使用するWPMLの対応が中途半端なのがめちゃくちゃ残念です。
shortcoderが一見、多言語化できたようにみえるのですが、いざショートコードを使用すると別の言語でページを表示しても、IDで指定されたショートコードしか表示されずぜんぜん多言語化されていません。
これを解消するにはWPMLでページ管理を分離してIDを書き換える必要があってちょっと手間です。
困っている人が他にもいた
こういった現象に困っている人はしっかりとフォーラムで質問したりしてくれているので、WPMLのフォーラムは優秀です。
https://wpml.org/forums/topic/automatically-translate-html-content-of-shortcoder-texts
プラグインで対応しているかのように見えて対応していない!という意見に、さらりとサポーターのアリさんが別の解決方法を提示してきています。
めちゃくちゃショートコードを登録している人だったら、激怒して返信もしないんじゃ・・と思う返し方ですが、自分の場合はまだ傷が浅かったのでめちゃくちゃ助かりました。
アリさん曰く、
1. From WP Admin -> Toolset -> Post Types, you can register a new custom post type and name it something like ‘Contents’.
In this post type, you can add each instance of reusable content that you’d like to use on Product pages or pretty much anywhere on your website.
The content that you are currently saving in each shortcode, can be stored as the body/content of each post in this new post type.
The translation of this content would work the same way as you translate your other posts and pages and you’ll only have to do it once for each of these posts.
2. Next, to load the content from these ‘Contents’ posts, you can register a new custom shortcode:
要するに、カスタム投稿タイプを作って、それを自分でショートコード化(function.php)すればいいじゃない!?そこでWPMLで多言語化バッチリになるね!
と書いてあります。
とりあえずToolsetという有料アドオンは購入していなかったのでCPT UIというおなじみのプラグインを使用してカスタム投稿タイプを追加することにしました。ちなみに、shortcoderはカテゴリを分けることができないのでそこも使い勝手がやや悪い点です。(だからテンポラリで使用しているんですがね)
カスタム投稿タイプを作って管理できる定番無料プラグイン。ほんと便利なのでインストール必須プラグインのひとつなので、今回のアリさんの提案には賛成。
アリさんのコード
add_shortcode('custom-content-shortcode', 'custom_content_shortcode_func');
function custom_content_shortcode_func($atts) {
$a = shortcode_atts( array(
'id' => '',
), $atts );
$target_post = apply_filters( 'wpml_object_id', $a['id'], 'content' );
$content = apply_filters( 'the_content', get_the_content(null, false, $target_post) );
$content = wptexturize( $content );
ob_start();
echo $content;
return ob_get_clean();
}
これをfunction.phpに記述すると
[custom-content-shortcode id='1234']
こんなかんじに投稿IDを指定したものを(たぶん主言語の投稿IDがおすすめ)コピペしておけば、別言語になった際は別言語のショトコ投稿IDに変わるのでショートコード多言語化が完成するよ!
・・と書かれていたのですが、半目で読まずにコピペして試してもぜんぜん多言語化されない。
さらに、アリさんのshortcoderガン無視の提案に怒ったのかスレ主も返信しておらず未解決のままなかば強制的に解決となってました。
半目でコピペするだけで使えるようになるのが優秀なフォーラムなのに・・と思いましたが、しっかりとコードを読んでWPMLの反応箇所などを確認して修正したコードがこちらです
カスタム投稿タイプをショトコ化してWPML対応させる
//カスタム投稿タイプをショトコ化してWPML対応させる
add_shortcode('specsc', 'custom_content_shortcode_func');
function custom_content_shortcode_func($atts) {
$a = shortcode_atts( array(
'id' => '',
), $atts );
$target_post = apply_filters( 'wpml_object_id', $a['id'], 'post' );
$content = apply_filters( 'the_content', get_the_content(null, false, $target_post) );
$content = wptexturize( $content );
ob_start();
echo $content;
return ob_get_clean();
}
// ↑使い方:[specsc id='1234']
ショートコードで呼び出す名前を変えてます。
アリさんが間違っていた部分は、投稿IDのコンテンツ部分(content)を指定していたのですが、記事(post)に変えたら見事にショートコードの多言語化が完成しました。
これで、自分の作業はめちゃくちゃ楽になりました。
ただ、アリさんのコードを読まずにコピペでテストをしていたのですが、ただでさえ工程が遠いのと多言語投稿まで構築してテストするので軽く半日ほど吹っ飛びました。やっぱりコピペで楽をしようとすると変なところで時間がかかるので気をつけようと思いました(上のコードはちゃんと動くのでコピペでおk)