[WordPress][プラグイン開発] 記事中のショートコードを保存時に書き換える

記事に挿入したショートコードを保存した時に書き換えてしまうプラグインサンプルを書きました。

[foo bar=”qux”] → 保存すると [foo bar=”qux” baz=”quux”] というような感じ。

なぜそんなことする必要があるのかというと、ショートコードの処理は毎回記事を表示するときに実行されるので、重たい処理はショートコードに含ませておこうというものです。

具体的には、Webサイトのスクリーンショットを表示 で作成したプラグインのショートコードが、Web サイトのタイトルを指定していないと毎回 Web サイトにアクセスするという動作をしているのに、今頃気付いたので、その解決策です。このプラグインは保存時にタイトルを取得するようアップデートしています。既存の記事は一度更新しないと毎回タイトル取得してしまいますが、プラグイン単体で良い感じにするのは思いつかなかったのでそのままです。

コード全体は jz5/wp-rewrite-shortcode-sample に置いてます。

ショートコード プラグインの作成

ショートコードのプラグイン作成は簡単です。add_shortcode でショートコードタグのフックを追加します。

[foo bar=”qux” baz=”quux”] というショートコードを書くと、(bar = qux, baz = quux) と表示するだけの簡単なものです。

保存時に書き換える

サンプルとして、ショートコードの baz 属性が指定されていなかった場合は、プラグインで値を決め本文中に書き換えてから保存するようにします。

新規作成と更新時時に処理するため wp_insert_post_data というフィルターをフックします。

$data['post_content'] の内容を書き換えます。サンプルでは baz 属性を指定していなければ uniqid() の結果が付けたショートコードに書き換えられます。

ショートコード部分の取得などは、Shortcode API を使います。リファレンスだと詳細不明で実際の shortcodes.php のコードも読んでました。

has_shortcode

Function Reference/has shortcode « WordPress Codex

まず対象のショートコードが本文に含まれるか確認に使っています。

get_shortcode_regex

Function Reference/get shortcode regex « WordPress Codex

ショートコードを表す正規表現を返す関数。この正規表現自体は [foo] のような閉じタグ([/foo])がない場合はうまくショートコード部分を取れません(が、フィルターに渡される本文データの場合上記コードで意図した動作になります)。

下記の結果を使っています。

  • $matches[0]: ショートコード全体([foo bar=”qux” baz=”quux”])
  • $matches[2]: ショートコードタグ(foo)
  • $matches[3]: ショートコード属性部分(bar=”qux” baz=”quux”)
  • $matches[1], $matches[6]: ショートコードのエスケープ記述([[foo]])の場合は [ と ] が入る

shortcode_parse_atts

Function Reference/shortcode parse atts « WordPress Codex

ショートコード属性部分(bar=”qux” baz=”quux”)を連想配列に変換します。上記で得られた結果は stripslashes 関数を通してから指定します。