MENU

【WordPress×PHP】フィルターフックの仕組みと使い方

【WordPress×PHP】フィルターフックの仕組みと使い方
目次

はじめに

【WordPress×PHP】アクションフックの仕組みと使い方では、決まったタイミングで処理を実行するアクションフックを解説しました。

今回は、もう1つのフックであるフィルターフックを解説します。フィルターフックを使うと、WordPressやテーマが表示しようとしている値(タイトルや本文など)を、表示される前に書き換えられます。第5回で予告した「SWELL以外のテーマでも本文の前にお知らせを入れる方法」も、実務サンプルで紹介します。

このシリーズの全15回の構成は、第1回の記事の冒頭にまとめています。

フィルターフックとは?

アクションフックの差し込み口がdo_action()だったのに対して、フィルターフックの差し込み口はapply_filters()です。

$title = apply_filters( 'the_title', $title, $id );

これはWordPress本体のget_the_title()の中にある1行です。記事のタイトルをthe_titleというフィルターに通して、その結果を$titleに入れ直しています。add_filter()で関数を登録しておくと、この値を受け取って加工し、返した値が新しいタイトルになります。

アクションフックとフィルターフックの違い。アクションフックは登録した関数を実行するだけで戻り値は使われない。フィルターフックはapply_filtersで渡された値を関数が受け取り、加工してreturnで返し、その値が表示に使われる
アクションフックフィルターフック
差し込み口do_action()apply_filters()
登録add_action()add_filter()
役割処理を実行する値を加工して返す
return不要必ず必要

add_filterの書き方

add_filter()の引数は、add_action()と同じ4つです(フック名、関数、優先度、受け取る引数の数)。違いは、関数の最後で値をreturnすることです。

記事のタイトルの前に「【PHP】」を付けてみます。

add_filter( 'the_title', function( $title ) {
	return '【PHP】' . $title;
} );

ローカル環境で記事を開くと、タイトルが「【PHP】Hello world!」になりました。受け取った$titleに文字を連結して、returnで返しているのがポイントです。

returnを忘れるとどうなるか

returnを書き忘れると、どうなるでしょうか。

add_filter( 'the_title', function( $title ) {
	$title = '【PHP】' . $title;  // returnを書き忘れた
} );

エラーは出ませんでしたが、記事のタイトルが空になりました。returnのない関数はnull(何もない)を返すため、その「何もない」がタイトルとして使われたのです。フィルターを追加したら表示が消えた、というときは、まずreturnを確認しましょう。

優先度:値は順番に受け渡される

同じフィルターに複数の関数を登録すると、優先度の小さい順に実行されます。ここまではアクションフックと同じですが、フィルターでは前の関数が返した値が、次の関数に渡されます。

add_filter( 'the_title', function( $title ) { return $title . '[20]'; }, 20 );
add_filter( 'the_title', function( $title ) { return $title . '[10]'; } );
add_filter( 'the_title', function( $title ) { return $title . '[5]'; }, 5 );

タイトルは「Hello world![5][10][20]」と表示されました。

複数のフィルターはバケツリレーのように値を受け渡す。Hello world!が優先度5、10、20の順に渡され、それぞれが末尾に[5]、[10]、[20]を付けて返した結果、Hello world![5][10][20]と表示された

ほかのプラグインやテーマが同じフィルターを使っているときに、自分の加工を最後に反映させたい場合は、優先度に大きな数字(20や99など)を指定します。

条件を付けずに登録すると、思わぬ場所まで変わる

先ほどの「【PHP】」を付けるコードを試したとき、変わったのは記事のタイトルだけではありませんでした。ページのHTMLを調べると、次の場所でもタイトルに「【PHP】」が付いていました。

条件を付けずに登録すると思わぬ場所まで変わる。the_titleでは記事タイトル、パンくずリスト、グローバルメニュー、ウィジェット、構造化データなどが変わった。the_contentでは投稿ページ・固定ページの本文とRSSフィードにお知らせが入った。条件を付けると投稿ページの本文だけに入った

the_titleは、記事やページのタイトルを取り出すあらゆる場所で使われるためです。同じように、本文に関係するthe_contentに条件なしでお知らせを追加すると、投稿ページだけでなく、固定ページの本文やRSSフィードにも入りました。

決まった場所だけを変えたいときは、第7回の条件分岐タグなどを使って、変えたくないときは受け取った値をそのまま返すようにします。

add_filter( 'the_content', function( $content ) {
	if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
		return $content;  // 何もせずにそのまま返す
	}
	return '<p>お知らせ</p>' . $content;
} );
条件意味
is_singular( 'post' )投稿ページを表示しているか
in_the_loop()ループ(第6回)の中で呼ばれているか
is_main_query()メインクエリ(そのページ本来の記事の取得)か

この3つを付けたところ、お知らせは投稿ページの本文だけに入り、固定ページとRSSフィードには入りませんでした。the_contentを使うときの定番の書き方なので、セットで覚えておきましょう。

よく使うフィルターフック

WordPress本体の代表的なフィルターフックです。

フィルター名受け取る値
the_title記事・ページのタイトル
the_content本文(ブロックのHTML)
excerpt_length抜粋の長さ
body_class<body>に付くクラス名の配列
upload_mimesアップロードできるファイルの種類

SWELL独自のフィルターフック

SWELLのテーマフォルダをapply_filters(で検索すると、swell_で始まるSWELL独自のフィルターフックが70種類以上ありました(SWELL 2.19.0)。アクションフック(4つ)よりずっと多く、SWELLの細かい動きはフィルターで変えられるようになっています。

たとえばsearchform.phpには、検索フォームの中に表示される文字(プレースホルダー)を決める次の1行があります。

$placeholder = apply_filters( 'swell_searchform_placeholder', __( '検索', 'swell' ) );

子テーマのfunctions.phpに次のコードを書くと、検索フォームの「検索」が「サイト内を検索」に変わりました。

add_filter( 'swell_searchform_placeholder', function( $text ) {
	return 'サイト内を検索';
} );

ほかにも、次のようなフィルターがあります。

フィルター名変えられること
swell_is_show_sidebarサイドバーを表示するか(true/false)
swell_is_show_index目次を表示するか
swell_related_post_maxnum関連記事の表示数(初期値は8)

true/falseを返すだけの関数

swell_is_show_sidebarのようにtrueかfalseを返すフィルターには、WordPressに用意されている__return_true・__return_falseという関数が便利です。

add_filter( 'swell_is_show_sidebar', '__return_false' );

この1行で、サイドバーが表示されなくなりました。実はSWELL自身も、lib/overwrite.phpの中で、記事ごとの「サイドバーを表示する/しない」の設定をこの書き方で反映しています。

登録したフィルターを外すときは、remove_filter()を使います。使い方と注意点(外す場所と優先度)は、第9回で解説したremove_action()と同じです。

フィルターの中でechoしてはいけない

フィルターの関数の中でechoを使うと、思わぬ場所に文字が出力されます。the_titleのフィルターの中でecho 'テスト';を実行したところ、1ページの中で12回も出力されました。

  • <head>の中のリンクを出力する直前(ページの一番上に文字が表示される)
  • グローバルメニューの項目名の前
  • パンくずリストの直前
  • 記事タイトルの前

フィルターは「値を受け取って返す」ための仕組みで、表示する場所を決めるものではありません。出力したいときはアクションフックを使い、フィルターではreturnで値を返すことを守りましょう。

実務サンプル:テーマを問わず古い記事の本文の前にお知らせを入れる

第5回の実務サンプルでは、SWELL独自のアクションフックswell_before_post_headを使って、最終更新から1年以上たった記事にお知らせを表示しました。これをthe_contentフィルターで書き直すと、SWELL以外のテーマでも使えるようになります。

子テーマのfunctions.phpに、次のコードを追加します(第5回のコードを使っている場合は、二重に表示されないよう、どちらか一方にしてください)。

/**
 * 最終更新から1年以上たった記事の本文の前にお知らせを入れる(テーマを問わず使える)
 */
add_filter( 'the_content', function( $content ) {
	if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
		return $content;
	}

	$modified = (int) get_the_modified_date( 'U' );
	if ( time() - $modified < YEAR_IN_SECONDS ) {
		return $content;
	}

	$message = 'この記事は最終更新日(' . get_the_modified_date( 'Y年n月j日' ) . ')から1年以上たっています。'
		. '内容が古くなっている可能性があります。';

	return '<p class="kurumico-old-notice">' . esc_html( $message ) . '</p>' . $content;
} );

CSSは第5回と同じものを、子テーマのstyle.cssに追加します。

.kurumico-old-notice {
	padding: 1em;
	margin-bottom: 2em;
	background: #fff8e1;
	border-left: 4px solid #f0a500;
	font-size: .9em;
}

2024年4月1日に公開した記事を開くと、本文の前にお知らせが表示されました。

SWELLの投稿ページ。タイトル「古い記事」の下、本文の1段落目の前に「この記事は最終更新日(2024年4月1日)から1年以上たっています。内容が古くなっている可能性があります。」というお知らせが表示されている

同じコードを、WordPressの標準テーマ「Twenty Twenty-Five」で表示した場合も、本文の前にお知らせが入りました。

Twenty Twenty-Fiveの投稿ページ。タイトル「古い記事」の下、本文の前に同じお知らせが表示されている

コードのポイントは次のとおりです。

  • the_contentはWordPress本体のフィルターなので、どのテーマでも使える
  • お知らせを表示しないときは、受け取った$contentをそのままreturnしている
  • お知らせはechoせず、本文の前に連結してreturnしている
  • 第5回(タイトルの上)とは違い、表示される位置は本文の前になる

よくある質問・エラー対処

Q. フィルターを追加したら、記事の本文やタイトルが消えました

→ 関数の最後のreturnが抜けていないか確認してください。条件分岐で途中で終わる場合も、すべての分かれ道で値をreturnする必要があります。


Q. 受け取る値が2つ以上あるフィルターはどう書きますか?

→ アクションフックと同じく、4つ目の引数で数を指定します。たとえばthe_titleは、タイトルと投稿IDの2つを渡すので、add_filter( 'the_title', function( $title, $id ) { … }, 10, 2 );と書けば、投稿IDも使えます。

おわりに(まとめ)

まとめ

フィルターフックを使えば、WordPressやテーマが表示しようとしている値を、表示される前に書き換えられます。

  • ✅ apply_filters()が差し込み口、add_filter()で値を加工する関数を登録する
  • ✅ 関数の最後で必ず値をreturnする(忘れると表示が消える)
  • ✅ 複数のフィルターは、優先度の順に値を受け渡していく
  • ✅ 条件を付けて、変えたくないときは値をそのまま返す
  • ✅ SWELLには70種類以上の独自フィルターがある
  • ✅ フィルターの中ではechoしない

次回は、WP_Queryを使って、好きな条件で記事一覧を自作する方法を解説します。ion」の仕組み、アクションフックについて解説します。解説します。

次回は、WP_Queryで記事一覧を自作する方法について解説予定です。

この記事が、少しでも誰かのお役に立てれば幸いです。

関連記事

当サイトの記事で使用したVBAなどのサンプルをDLできます

この記事のサンプルはありません!

ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!


【CSS】テキスト関連プロパティについて基本解説|Webの基礎


よかったらシェアしてね!
  • URLをコピーしました!
目次