WordPress
記事本文や抜粋の文字数を制限する時にはHTMLエンティティに注意する

投稿 | | カテゴリー WordPress, PHP
記事本文や抜粋の文字数を制限する時にはHTMLエンティティに注意する

WordPressでも、トップやカテゴリーのページなど記事一覧では抜粋や本文は文字数を指定して表示する場合が多いと思います。このブログでも自前のコードで文字数制限していますが、それが原因でバリデータに引っかかってしまったので修正したメモです。

文字列から指定した数だけ文字数を取り出すには、PHPではmb_substr()を使います。文字列を切り出す場合はたいてい平文として扱うことが多いので、ボクはstrip_tags()でHTMLタグを取っ払ってからトリミングしています。

WordPressでmb_substr()で記事本文の最初30文字を抜き出して表示する例
<?php echo mb_substr ( strip_tags( $post->post_content ), 0, 30) . '…'; ?>

ただし、文字列を決まった文字数でバッサリと切り出す場合は、HTMLタグだけでなくHTMLエンティティ(文字参照)にも注意しないといけません。切り取った部分に「HTMLエンティティ」がかかっていると、参照に使われる文字が表示されてしまったり「&」が残ってHTMLの構文エラーになってしまう可能性があります。

自分で作ったプログラムとかでは文字を切り出す時の注意の一つとして頭にあった内容ですが、WordPressではあまり真剣にコード見ないので対応するのを忘れていました。

mb_substr()で、参照に使われる文字や「&」が残ってしまう例
<?php
$text = "&lt;b&gt;あいうえお&lt;/b&gt;かきくけこ&lt;b&gt;さしすせそ&lt;/b&gt;";
echo mb_substr ( strip_tags( $text ), 1, 30);
?>

> lt;b&gt;あいうえお&lt;/b&gt;かきくけこ&l

正しいソースを吐き出すために、最初にstrip_tags()でHTMLタグを取っ払ったら一度html_entity_decode()でHTMLエンティティを文字列に変換します。それをmb_substr()で切り出してからhtmlentities()でHTMLエンティティを元に戻します。

<?php
$text = "&lt;b&gt;あいうえお&lt;/b&gt;かきくけこ&lt;b&gt;さしすせそ&lt;/b&gt;";
// HTMLタグを取り除く
$text = strip_tags( $text );
// HTMLエンティティを文字列に変換
$text = html_entity_decode( $text );
// 指定の文字数で切り出す
$text = mb_substr( $text, 1, 30 );
// HTMLエンティティを元に戻す
$text = htmlentities( $text );
// 出力
echo $text;
?>

> b&gt;あいうえお&lt;/b&gt;かきくけこ&lt;b&gt;さしすせそ&lt;/b&gt;

例では、出力時に先頭の「<」がなくなってしまいますが構文エラーは起きていません。代入を繰り返すのは野暮ったいので実際のコードは下みたいな感じになると思います。

<?php
$text = "&lt;b&gt;あいうえお&lt;/b&gt;かきくけこ&lt;b&gt;さしすせそ&lt;/b&gt;";
echo htmlentities( mb_substr( html_entity_decode( $text ), 1, 30 ) );
?>

以上、文字列をバッサリ行くときはHTMLタグだけでなくHTMLエンティティにも気を付けないとバリデーションに引っかかってアレレとなるよ、という自分のためのメモでした。HTMLタグを表記したりしなければあまり困ることもないと思いますが、自前でトリミングする際の参考になれば幸いです。