この記事は約 7 分で読めます。

WordPressで投稿本文の文字列を取得する方法はいろいろありますが、出力形式によってはWPの自動整形機能(wpautop) により意図しないコードが挿入されたり、Gutenbergエディターを使用している場合は自動生成されたHTMLタグや、コメントタグが含まれるケースがあります。
ここではブログ記事のリストなどでよく見られる、本文から指定文字数を抜粋して掲載する方法をいくつか紹介いたします。

本ページで奨励している最適解だけを読みたいは、目次から「まとめ」まで飛んでいただければ幸いです。

投稿本文の文字列の取得方法

本文から文字列を抜き取って出力する方法はいくつかありますが、 文字数を制限して取得する方法と合せて紹介したいと思います。

本サイトでもブログ記事一覧のブロックで実装しており、編集時のエディターはGutenbergを使っています。

投稿の抜粋を表示させるget_the_excerpt()を使った方法

文字数カウントの正確性:抜粋からの取得時は正確、投稿本文からの取得時は不正確
レイアウト崩れの危険性:なし(但し抜粋からの取得時は文字数によってはあり)

記事編集画面の「抜粋」に入力した文字列を取得させるget_the_excerpt()ですが、単純にget_the_excerpt() のみで出力した場合は、抜粋に入力した文字列全てが問題なく表示されました。

もし抜粋が空欄の場合は本来は投稿本文から55文字を取得して表示されます。
但し今回のケースだと、純粋な投稿本文以外のWPやエディターが自動で生成するソース上のタグ?が認識されてカウントに含められている影響なのか、55文字にはなりませんでした。

echo get_the_excerpt();

次に上記にmb_substrを加えて文字数制限(66文字)を加えたパターンです。
式はmb_substr(対象文字列, 開始位置, 取得文字数, ‘ エンコーディング ‘)となります。
ちなみに66文字というのは本サイトで指定している文字数です。

echo mb_substr(get_the_excerpt(), 0, 66, 'UTF-8');

抜粋に文字列の入力がある場合は、狙った通りに66文字が取得できました。(半角英数字が含まれる場合、1文字分前後する場合はあります)
抜粋が空欄の場合は投稿本文から文字列を取得するのですが、やはり66文字にはなりませんでした。

get_the_excerpt() を使う場合、抜粋から文字列を取得する場合は問題ないが、抜粋が空欄で投稿本文より文字列を取得する場合は、純粋なテキスト以外のソースコードも含んでしまうため、正確性に欠けるという感じになりました。

試しにfunctions内でフィルターフックを設定して文字数制限をかけても同様の現象となりました。

これはあくまで予想ですが、Gutenbergエディターで編集した時に生成される独自のコードが文字数カウントの解釈に含まれてしまっているのかもしれません。

以下get_the_excerpt() に関する引用を掲載しますのでご参考までに。

もしも投稿に抜粋が設定されていない場合、この関数は投稿内容に wp_trim_excerpt を適用し、55単語を抜き出して概要を生成します。この時生成された文字列の後ろには “[…]” が付加されます。wp_trim_excerpt は get_the_excerpt フィルターを経由して適用されますが、これは削除可能です。

パスワードで保護されたページでは、”There is no excerpt because this is a protected post.” という初期値の文字列を返します。この文字列は関数定義の段階で変更可能です。

もし投稿に抜粋があり、パスワード保護もされていない時は、抜粋欄に入力した文字列を返します。

引用元: テンプレートタグ/get the excerpt – WordPress Codex 日本語版

整形前の投稿本文をそのまま取得する$post->post_contentを使った方法

文字数カウントの正確性:不正確(本文以外のHTMLタグを含んで出力される)
レイアウト崩れの危険性:あり

エディター等で書かれたHTMLタグを含めた本文がそのまま入った状態で出力されるのが$post->post_contentの特徴です。

Gutenbergエディターでの編集時に自動的に出力される<!– wp:paragraph –>などのコメントタグや文中の<br>タグなどもそのまま出力されます。

$content= mb_substr($post->post_content, 0, 66, 'UTF-8');
echo $content.'…';

それらのソースコードも文字数カウントされるため、ページ上に表示される本文テキストの文字数は実際に指定したものよりも短くなってしまいます。

しかしながら$post->post_contentの最大のリスクは冒頭で「レイアウト崩れの危険性:あり」と書いたようにレイアウトが崩れてしまう危険性がある、という点でしょう。

実際に本サイトでも当初は深く考えずに$post->post_contentで一覧の文字数取得を行っていたのですが・・・特定の状況下で見事にレイアウトが崩れてしまいました。

特定の状況下についてですが、エディターが自動的に出力するHTMLタグの開始タグのみが抜粋される文字列に含まれて出力されてしまい、閉じタグが含まれないため結果としてレイアウト崩れを誘発する、といった内容です。

$post->post_contentは使い方によっては活用できるシーンはあるかと思いますが、今回のようなケースでは使用しない方がよいでしょう。

文字列からHTMLタグを取り除いて取得するwp_strip_all_tagsを使った方法

文字数カウントの正確性:不正確(取得元のソースに依存)
レイアウト崩れの危険性:なし

このwp_strip_all_tags関数は非常に便利で、取得した文字列からscriptやstyleも含んだあらゆるHTMLタグを除去してくれるのに加えて、第二引数にtrueを指定すると、2つ以上の連続する改行または空白(タブを含む)を半角スペース1つに置換してくれます。 (第二引数を設定しない場合、初期値はfalseとなります)

さてこのwp_strip_all_tagsを使ったケースではどうでしょうか。

$content= wp_strip_all_tags(mb_substr(get_the_content(), 0, 66, 'UTF-8'), true);
echo $content.'…';

これまたこの章の冒頭に記載しているので既に答えは出ていますが(笑)残念ながら取得する文字数は不正確です。

但しこれはwp_strip_all_tagsが原因というよりは、get_the_content()で文字列を取得している段階で既に不要なコードを含んだ文字数で文字列を取得しているためです。

ここまでの挙動を見るに、文字数カウントの認識に関しては恐らくGutenbergエディターが自動生成するコメントタグが原因なのかな、と思ったりもしていますが、厳密に検証したわけではないので・・・後日原因が判明した際に加筆修正します

また、wp_strip_all_tags関数はあらゆるHTMLタグを除去する、とお伝えしましたが唯一WPのショートコードだけは除去せずにそのままの文字列で出力されてしまいます。

今回のケースに限らず、もしショートコードがそのまま出力されてしまう場合はstrip_shortcodes()で文字列からショートコードを除去、remove_shortcode()で特定のショートコードを除去することが可能ですのでご参考までに。

指定文字数を切り出して取得するwp_trim_wordsを使った方法

文字数カウントの正確性:基本的には正確(一部不正確)
レイアウト崩れの危険性:なし

最後になりますが、wp_trim_words関数は、HTMLタグを除去した上でテキストの先頭から指定された文字数を切り出して表示させることが可能で、文字列の取得と文字数制限がセットになった便利な関数です。

式はwp_trim_words(対象文字列, 取得文字数, ‘ 切り出した文字列の後に追加したい文字 ‘)となります。
第三引数には文字列以外に<a href=”xxx.html”>続きを見る</a>といったようなHTMLコードを入れることも可能です。

echo wp_trim_words(get_the_content(), 66, '…' );

結論から先に述べますが、この方法がいかなる状況下においても最もプレーンなテキストを取得できます。

但し、WPのショートコードが通常の文字列として扱われ、改行・余白なども認識してしまうので、もう一工夫が必要です。

【改良版】wp_trim_wordsを使った方法

文字数カウントの正確性:正確
レイアウト崩れの危険性:なし

上記wp_trim_wordsに一工夫加えた改良版です。

$remove_arrayには除去対象の改行コードや余白を配列として格納します。
strip_shortcodesで取得する文字列からショートコードを除去します。
str_replaceで除去対象として登録した配列内容を空白の”に置き換えて除去します。

$remove_array = ["\r\n", "\r", "\n", " ", " "];
$content = wp_trim_words(strip_shortcodes(get_the_content()), 66, '…' );
$content = str_replace($remove_array, '', $content);
echo $content;

意図した通り投稿本文からプレーンテキストで指定文字数にて文字列を切り出して表示させることができました!

まとめ

投稿本文の文字数を制限してテキストのみで取得する方法について今回はget_the_excerpt()、$post->post_content、wp_strip_all_tags、wp_trim_wordsの4パターンに絞ってお伝えしました。

本ケースでは投稿本文からHTMLタグ・改行・スペース・ショートコードを除去した完全なプレーンテキストとして文字列を取得すること、そしてエディターやWPが自動生成するコードを含むことなく意図した指定文字数で表示させることに主眼を置いて検証しました。

その結果、本ケースでの最適解は【改良版】wp_trim_wordsということになりました。

ここでご紹介した方法以外にもまだまだやり方はありますし、ケースバイケースで最適解は変わってくるかもしれませんが、その時々の状況に応じて最適な方法を選択していただければと思います 。

弊社では補助金を活用したECサイト構築支援やWordPressやshopifyに関するご相談、サイト診断や運用サポートに関する内容など、幅広い業種・業態のWeb制作・ホームページに関する無料相談を承っています。オンライン相談も実施していますので、お気軽にご相談ください。
無料で相談してみる