定型文追加とフック:WordPress

WordPressで決まった内容を、投稿に追加する方法を前回の記事で書きました。
その続きです。

WordPressのフックは大きくアクションとフィルターに分けられます。

  • ハンドラで処理した値を利用しないのがアクション
  • ハンドラで処理した値を利用するのがフィルター

WordPressのフック機構はイベントモデルです。

  • add_action()/add_filter()、関数でイベントハンドラを登録
  • do_action()/apply_filters()関数でイベントを発火

投稿内容を出力するthe_content()テンプレートタグが実行されるときに適用されるthe_contentフィルターについて詳しく見ます。

the_contentフィルターにハンドラを登録するには前述したようにadd_filters関数を使います。

add_filter( 'the_content', function ($content) {
    return $content . '(^o^)';
}, 10);

これですべての投稿の末尾に(^o^)が追加されます。

次に実用的な例を参考にもう少しフック機構について調べてみます。
追加する機能の要件は以下のようになります。

  1. すべての投稿に投稿IDが1の記事を追加
  2. 投稿本文のh1〜h6タグから自動的に見出しを作成するTable of Contents Plusプラグインを使用
    • プラグインはthe_contentフィルターとして登録
    • 投稿IDが1の記事のh1〜h6も見出しとして認識させたい

要件2を考えて、今回はthe_contentフィルターを使って投稿IDが1の記事を追加することにします。

投稿本文はwp_postsテーブルのpost_contentフィールドに格納されています。
post_contentフィールドは、投稿エディタから入力した値そのものを格納しています。

the_content()テンプレートは以下のように短い関数です。

// 著者注 簡潔にするためコメントを削除しています
function the_content( $more_link_text = null, $strip_teaser = false ) {
    $content = get_the_content( $more_link_text, $strip_teaser );

    $content = apply_filters( 'the_content', $content ); // 著者注 --- (1)
    $content = str_replace( ']]>', ']]>', $content );
    echo $content;
}

上記のように、the_content()は主に、post_contentフィールドの値に対して、(1)でthe_contentフィルターを適用して出力します。

フィルターには、複数のハンドラが登録されています。
the_contentフィルターにも複数のハンドラが登録されています。

the_contentフィルターに登録されているハンドラはグローバル変数$wp_filterで確認できます。

<?php
    echo sprintf('<pre>%s</pre>', print_r($wp_filter['the_content'], true));
?>

出力は以下のようになります。

WP_Hook Object
(
    [callbacks] => Array
        (
            [8] => Array
                (
                    [00000000293c695700000000436e65a5run_shortcode] => Array
                    // 著者注 .... (省略)       
                )

            [10] => Array
                (
                    [wptexturize] => Array
                        (
                            [function] => wptexturize
                            [accepted_args] => 1
                        )

                    [wpautop] => Array
                        (
                            [function] => wpautop
                            [accepted_args] => 1
                        )
                   // 著者注 .... (省略 

                )
                // 著者注 .... (省略


                )

            [100] => Array
                (
                    [00000000293c694800000000436e65a5the_content] => Array
                        (
                            [function] => Array
                                (
                                    [0] => toc Object ---(1)
                     // 著者注 ...

                )

            )
    )   
)

WordPressは、イベントハンドラを登録するadd_filter()関数の第3引数で優先度を指定できます。

優先順位の低いものから順に実行されます。
優先度が同じ場合は追加した順番で実行されます。

the_contentの場合だと、優先度8にrun_shortcode関数、優先度10ではwptexturize関数、wpautop関数が実行されます。
例えばwpautop関数は複数改行を段落タグへ変換します。

またTable of Contents Plusが見出しを作成処理は優先度100で実行されます。

以下の例では、追加されるIDが1の投稿本文には、run_shortcode関数しか適用されないので、望む表示にならない可能性があります。

add_filter( 'the_content', function ($content) {    
    return $content .=  get_post(1)->post_content;
}, 10);

get_post(1)->post_contentはWP_POSTオブジェクトのpost_contentプロパティでwp_postsテーブルのpost_contentフィールドの値を取得します。

ここで優先度を7にすることでthe_contentフィルターの処理をすべて適用できます。

add_filter( 'the_content', function ($content) {
    return $content .=  get_post(1)->post_content;
- }, 10);
+ }, 7);

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。