記事の抜粋が110文字になる理由、ご存じですか?
記事の抜粋は110文字。WordPressを使い慣れた方はご存じと思いますが、なぜ110文字になるのか、わかりますか?
「どこかに110って書いてあるんでしょ」という理解で十分ですが、その仕組みを追いかけることはないかもしれません。そこで、たまには予備知識を付けるためWordPressの内部に踏み込んで、抜粋が110文字になる理由を探ってみましょう。探ってみると、WordPressカスタマイズにとって重要な考え方がわかりますよ。
この記事の内容
抜粋を表示するthe_excerpt関数
使用中のテーマに含まれるテンプレート(例:archive.phpやindex.phpなど)を見ればわかるかもしれませんが、投稿の抜粋を表示する命令はthe_excerptという関数です。そこで、WordPress本体のwp-includes/post-template.phpに記述されたthe_excerpt関数のコードを見てみましょう。内容はシンプルです。
function the_excerpt() { echo apply_filters( 'the_excerpt', get_the_excerpt() ); }
たった3行のコードですが、これを理解すればWordPressの仕組み、そして、WordPressカスタマイズの根本原理がわかると言っても過言ではありません。過言かもしれませんが、使われている命令を1つずつ見ていきましょう。
オリジナル関数を作成する「function」
「function」はオリジナルの関数(ユーザー定義関数)を作成する構文です。次のように関数名を付けて、実行したいコードを記述するのが一般的な書式です。
function 関数名() { …実行したいコード… }
the_excerpt関数の例では、次のように「the_excerpt」という名前を付けて、抜粋を表示するためのコードを記述します。これにより、テンプレートファイルで「the_excerpt();」と記述すると記事の抜粋が表示される仕組みです。
function the_excerpt() { 抜粋を表示する }
画面に文字を表示する「echo」
抜粋を画面に表示するのはechoという命令です。一般的な使用例は次のようになります。
echo "テスト";
ただし、記事の抜粋を表示したい場合、「テスト」のような固定の文字を指定するわけにはいきません。そこで、記事の抜粋を取得する get_the_excerpt関数などと組み合わせて次のように記述することができます。
echo get_the_excerpt();
これにより、固定の文字ではなく、取得した抜粋を表示することができます。
表示する前に文字を加工する「apply_filters関数」
単純に記事の抜粋を表示するだけなら、上記のコードで完成です。つまり、the_excerpt関数は次のようなコードでも良いはずです。
function the_excerpt() { echo get_the_excerpt(); }
これでも問題ありませんが、抜粋を表示する前に加工したいこともありますよね。たとえば、「110文字じゃなくて50文字にしたい」とか、「不要なタグを取り除いて表示したい」などです。そこでWordPressでは、抜粋に限らず取得した文字を表示する直前に加工するフィルターフックという仕組みが組み込まれています。
急に難しくなったように思うかもしれませんが、フィルターフックとは「取り出した文字を表示する直前に加工する」のだと思えば大丈夫です。ここでは、get_the_excerpt関数で取得した抜粋を少し加工してから表示したいのです。そのため、apply_filters関数でフィルターをかけて加工しています。具体的には次のようなコードになっています。
echo apply_filters( 'the_excerpt', get_the_excerpt() );
この「the_excerpt」は関数のことではなく、文字を加工するタイミング(フィルターフック)のことです。ですから、上記のコードを解釈すると「get_the_excerpt関数で取得した抜粋をthe_excerptフィルターフックのタイミングで加工して画面に表示する」となります。ちなみに、フィルターフックで加工する処理が指定されていない場合は、取得した文字がそのまま表示されます。なんと便利な仕組みなのでしょう。フィルターフック!
フィルターフックのコンセプトは、取得した文字を直接修正するのは危険なため、外部ユーザーが文字を加工できるように「フック」というタイミングが準備されているということです。プラグインやテーマの本体を修正せずにカスタマイズできるようになります。「取得・加工・表示」の流れをイメージできるようにしましょう。
また、話が長くなるので説明しませんが、フックにはフィルターフックとアクションフックの2種類があります。何らかのタイミングでひと手間加えるという意味では、どちらも同じような仕組みです。
the_excerpt関数のまとめ
どうでしょうか。たった3行のthe_excerpt関数ですが、学習するには充実の内容でしたね。WordPressの根本原理を理解するための命令がつまった象徴的な関数です。
function the_excerpt() { echo apply_filters( 'the_excerpt', get_the_excerpt() ); }
使われている命令と処理の流れをまとめておきます。
- get_the_excerpt関数で記事の抜粋を取得する
- 取得した抜粋をapply_filters関数で加工できるようにする
- 加工するタイミングはthe_excerptフィルターフック
- 加工した抜粋をechoで表示する
- 上記の内容をfunctionでthe_excerpt関数として定義する
- テンプレートからthe_excerpt関数を呼び出すと抜粋が表示される
実はWordPressの本体はfunction(関数)とフックの集合です。the_excerptやthe_contentなど、簡単に呼び出して使えるWordPress関数が膨大に定義されており、必要に応じて動作を変更できるように、膨大なフックが設定されているのです。ですから、WordPress本体の仕組みを理解したり、PHPを使ったWordPressカスタマイズを深く理解するには、このfunctionとフックを重点的に学習することをおすすめします。ただし、簡単なホームページを作りたいだけなら、その努力は不要ですが。
さて、話が長くなりましたが、この記事の本題は「抜粋が110文字になる理由」でしたね。その「110」の答えが出てきていないので、続いて、抜粋を取得するget_the_excerpt関数を見て探っていきましょう。
抜粋を取得するget_the_excerpt関数
get_the_excerpt関数はthe_excerpt関数と同じようにwp-includes/post-template.phpに記述されています。少し複雑なので、主なコードを抜き出してみます。
function get_the_excerpt( $post = null ) { $post = get_post( $post ); …略… return apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ); }
get_post関数で1件の投稿を取得して、抜粋($post->post_excerpt)に対してget_the_excerptというフィルターフックをかけて抜粋を完成しています。わかりづらいかもしれませんが、「$post」が1件の投稿データで、その投稿に含まれる抜粋が「$post->post_excerpt」です。編集画面の「抜粋」に入力した内容です。
「…略…」の部分には「先頭から110文字を抽出する」のような具体的なロジックは書かれていないので、110文字の謎を解明するには、get_the_excerptフィルターフックを追いかける必要がありそうです。この部分で何らかの加工が行われているのかもしれません。
抜粋を加工するget_the_excerptフィルターフック
get_the_excerptフィルターフックを調べて、抜粋が110文字に切り取られる仕組みを見てみましょう。wp-includes/default-filters.phpを見ると、次のようなコードが記述されています。
add_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
add_filter関数は、指定されたフィルターフックで実行する関数を登録する関数です。ここでは、get_the_excerptフィルターフックでwp_trim_excerpt関数を実行するようになっています。関数名から察すると、110文字への切り取りは、このwp_trim_excerpt関数で行われているような気がします。続けて探っていきましょう。
本文を切り取るwp_trim_excerpt関数
get_the_excerptフィルターフックで実行されるwp_trim_excerpt関数を見てみましょう。wp-includes/formatting.phpに記述されています。以下、処理に関係する部分だけを抜き出します。見づらくて恐縮ですが。
$text = get_the_content(''); $text = strip_shortcodes( $text ); $text = apply_filters( 'the_content', $text ); $excerpt_length = apply_filters( 'excerpt_length', 55 ); $excerpt_more = apply_filters( 'excerpt_more', ' ' . '[…]' ); $text = wp_trim_words( $text, $excerpt_length, $excerpt_more ); return apply_filters( 'wp_trim_excerpt', $text, $raw_excerpt );
$textに抜粋の文字が作成され、加工され、最終的に$textに対してwp_trim_excerptフィルターフックが適用されて抜粋が完成する流れです。注目したいのは次の2つです。
- (5行目)$excerpt_length = apply_filters( 'excerpt_length', 55 );
抜粋文字数($excerpt_length)を確定します。フィルターフック(excerpt_length)を使って変更することもできます。初期設定は55文字です。 - (8行目)$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
指定文字数で抜粋を切り取るwp_trim_words関数を呼び出します。
5行目で抜粋の文字数を確定し、8行目ではその文字数で抜粋を切り取っています。抜粋文字数を確定する部分を追いかけてみましょう。
抜粋文字数を指定するexcerpt_lengthフィルターフック
上記の5行目の「55」を見てピンときた方はカンが鋭いです。「55×2=110」ですよね。ただし、この「55」を変更すれば文字数を増やしたり減らしたりできると思うのは早とちりです。試しに、この55を10にしても、抜粋の文字数は110文字のままです。
また、基本的にはwp-includesフォルダ内のファイルは変更禁止です。ここでは、あくまで検証用に変更しているだけです。WordPressをカスタマイズするといっても、決してwp-adminフォルダやwp-includesフォルダのファイルを変更してはいけません。
どこで「110」が設定されるのか。次の2行(上記コードの5行目と8行目)に注目です。
$excerpt_length = apply_filters( 'excerpt_length', 55 ); $text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
抜粋文字数($excerpt_length)を8行目のwp_trim_words関数に渡しているように見えます。110文字の謎を突き止めるには、$excerpt_lengthに対して適用されるexcerpt_lengthフィルターフックを追いかける必要がありそうです。
$excerpt_length = apply_filters( 'excerpt_length', 55 );
このフィルターフックは「抜粋文字数($excerpt_length)はexcerpt_lengthフィルターフックで変更できます。フックを適用しない場合は55になります」という意味です。つまり、「55」は単なる初期設定であって「日本語のときは2倍して110にする」という関連性はありません。
文字数を設定するWP Multibyte Patchプラグイン
excerpt_lengthに対してフックをかけて文字数を「110」に変更しているプラグインやテーマを探せば答えが見つかります。探してみましょう、と言いたいところですが果てしない作業になるので、答えを書いておきます。
それはWP Multibyte Patchプラグインです。プラグインファイル(wp-content/plugins/wp-multibyte-patch/wp-multibyte-patch.php)を見ると、次のようなコードが見つかります。
add_filter( 'excerpt_length', array( $this, 'excerpt_mblength' ), 99 );
抜粋文字数のexcerpt_lengthフィルターフックに対してexcerpt_mblength関数を実行するように設定されています。ということは、「110」の答えはexcerpt_mblength関数にあるかもしれません。
抜粋文字数「110」を設定するexcerpt_mblength関数
WP Multibyte Patchプラグインのexcerpt_mblength関数(wp-multibyte-patch.php)を見てみましょう。
function excerpt_mblength() { …略… $length = (int) $this->conf['excerpt_mblength']; …略… return apply_filters( 'excerpt_mblength', $length ); }
抜粋文字数($length)を conf['excerpt_mblength'] から取得して、excerpt_mblengthフィルターフックで変更可能にしています。この「取得して加工」という流れは、ここまで探ってきた関数やフィルターフックの仕組みと同じです。
conf['excerpt_mblength']はWP Multibyte Patchプラグインの中で次のように設定されています。
var $conf = array( 'excerpt_mblength' => 110, …略…
PHPに慣れていない方はピンとこないかもしれませんが、ついに「110」が見つかりました!この「110」が「先頭から110文字が表示される」の答えです。excerpt_mblengthフィルターフックに追加の加工指定がなければ、抜粋文字数は110で確定します。
試しに、この110を20などにすれば文字数が変わるので、ここが影響していることが理解できるでしょう。
とはいえ、本格的に運用するにはプラグイン本体を直すのは厳禁です。抜粋の文字数を変更するには上記のexcerpt_mblength関数で指定されていたexcerpt_mblengthフィルターフックを利用します。ここでも、「110」を取得してフィルターフックで加工するという流れですね。
/* 抜粋文字数を変更する */ function my_excerpt_length() { return 10; } add_filter('excerpt_mblength', 'my_excerpt_length');
このコードをテーマのfunctions.php(または子テーマのfunctions.php)にコピーペーストすれば、抜粋文字数が10文字に変更されます。
お疲れ様でした!これで抜粋の文字数が「110」になる理由にたどり着きました。
まとめ
以上、the_excerpt関数を呼び出したときに110文字の抜粋が表示される仕組みを追いかけてみました。結局、WP Multibyte Patchプラグインのおかげだったということです。WordPressの入門書に「WP Multibyte Patchプラグインは必ず有効化しましょう」と書かれている1つの理由はこのためです。
抜粋文字数を変更する方法をインターネットで検索すると「このコードをfunctions.phpにコピーペーストしてください」のような簡単な説明と共に数行のサンプルが見つかるだけですが、その仕組みを探っていくと、意外と複雑でしたね。
複雑だったとはいえ、冷静に見ると「関数を呼び出して取得した文字を表示直前に加工する(フィルターフック)」という流れの連続だったはずです。この「文字を取得してフックをかける」という作法は、一歩進んだWordPressカスタマイズを行うときに重要な考え方です。
プラグインから出力される文字をカスタマイズしたい場合、プラグイン本体を修正するのではなくフックを利用すれば安全ということです。この記事はthe_excerpt関数を例に説明しましたが、その他のカスタマイズでも共通の考え方なので、しっかり理解できるようにしましょう。