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');