現役プログラマのWordPressカスタマイズ相談

WordPress(ワードプレス)のお悩み、うまくいかなくてお困りなこと、不具合調査、新規制作依頼まで、ウェブアプリケーションエンジニアがあなたをサポートします。

functions.phpでフィルターフックを使い本文の内容をカスタマイズする

記事本文内にいくつかのキーワード文字列が含まれるときに対象文字を削除して欲しいとのご依頼がありました。

ブログはWordPressをお使いで、functions.phpにて対応することをご希望されていました。

またキーワード文字列は特定のDiv(クラス指定)の中だけという条件付きです。

なかなか複雑な対応が予想されます。


どのように対応したか実際のサンプルコードとともに解説します。

WordPressのフィルターを使う

ワードプレスには処理の後(または前)に独自の処理を追加する仕組みが用意されています。

functions.phpの中に add_filter や add_action というものを見たことがある方も多いはずです。


フックと呼んだりもするのですが、このような仕組みを使って記事本文表示をカスタマイズしたいと思います。

WordPressのフィルター

データベースに追加する前やブラウザのスクリーンに送り出す前にさまざまなタイプのテキストを改造するために WordPress が起動させるフックです。

プラグインは、フィルター API を使用して、これらのタイミングで特定のタイプのテキストを改造するために一つ以上の PHP 関数の実行を指定することがきます。

プラグイン API - WordPress Codex 日本語版

本文の加工は the_content

今回は記事表示後にフックしたいのでthe_contentというフィルター(?パラメータ?なんと呼ぶのかな)を使います。

the_content

データベースから取得した投稿コンテンツを画面に出力する前に適用される。
トラックバックなどの他の操作にも使われる)

プラグイン API/フィルターフック一覧 - WordPress Codex 日本語版

特定のキーワードの置換

特定のキーワードの置換は

str_replace

が便利です。

<?php
置換後の文字列 = str_replace("検索する文字列", "置換後の文字列", 元の文字列);

検索する文字列は配列にもできます。

空白を除去するサンプルはこんな感じです。
半角スペース、全角スペースを配列にして除去します。

<?php
$before = "A BC D E FG HI";
$after = str_replace(array(" ", " "), "", $before);
echo $after; //ABCDEFGHI

<2017/2/18 追記>
strtrという関数もあります。

文字列全体に置換パターンを適用したい場合 → str_replace()
文字列に1回だけ置換パターンを適用したい場合 → strtr()
 
hiroheroさんの記述を引用 http://qiita.com/hirohero


デバッグした際に変換後の文字列に気づくとは思いますが、
思い込みが思わぬバグにもつながります。
置換関数には注意が必要です。
qiita.com



正規表現検索後、コールバック関数を使い置換

今回はdivのクラスを解析する必要があります。
正規表現で検索し、対象の文字列を加工します。

今回は、
preg_replace_callback

という関数を使います。

<?php
//抽出パターン div.keywordを対象とする
$pattern = "/<div class=\"keyword\">(.*?)<\/div>/s";
$result = preg_replace_callback($pattern, function ($matches) {
    	
	//一応確認のため	
	//var_dump($matches);

	$str = $matches[1];

	//ここで加工処理を行う
	:
	:
	:
	return $str;
}, $text);

//結果を表示する
echo $result ;


こうすることで本文中に含まれる全てのdiv.keyword(いくつあっても大丈夫)を1つずつ抽出し文字を加工することができます。

サンプルコード

<まとめ>
WordPressの本文が対象→functions.php
・div.keyword内を対象とする
・10文字以上は三点リーダ
・キーワード文字列は除去する

<サンプル>
コメントに処理の詳細を記載しています。不明なところがあればココナラ、WoW!meよりお気軽にご相談ください

<?php
/**
 * 本文のキーワード置換処理&10文字以上は三点リーダーにする
 * add_filterで定義した第2引数のメソッド
 * @param $contents 記事本文が自動的に入る
 */
function disp_contents($contents){
	//抽出パターン
	$pattern = "/<div class=\"keyword\">(.*?)<\/div>/s";
	return preg_replace_callback($pattern, function ($matches) {
    		//変換対象となる文字列→str_replaceで除去する
		$search = array(Apple','Pineapple',Orange');
		//文字数制限を10文字で設定
		$max = 10;
		//正規表現でhitした文字列 index 0はdivを含み、index 1はdivの中となる
		$ori_str = $matches[1];
		//対象文字列を除去する
		$convert_str = str_replace($search, "", $ori_str);
        	//文字列の長さを取得する
		$len = mb_strlen($convert_str);
		//10文字以上かどうかを判定
		if ($len > $max) {
			//10文字以上なので三点リーダーをつけて返す
			$str = '<div class="keyword">' . mb_substr($convert_str, 0, $max) . '...</div>';
			return $str;
		} else {
			//そのまま返す
			return '<div class="keyword">' . $convert_str . '</div>';
		}
    }, $text);
}
add_filter('the_content', 'disp_contents');