抜粋の末尾に付く<とか&nbsとか>やらを削除する方法【ワードプレス】
ワードプレスで抜粋表示ってよく使いますよね。最近の多機能なWordPressテーマでは、カテゴリーページで全文表示と抜粋表示を切り替えられたりして、とても便利です。でもこの抜粋表示、たま~に末尾にRとか&nbsやら&lとか>とか、&で始まる意味のわからない文字が出現してしまいます。なんだか、しくじってる感じがしてカッコ悪いですよね。
そこで今回は、抜粋の末尾に付く、&から始まる意味不明の文字を削除する方法です。
~ 目次 ~
原因はエスケープ
この辺は読み飛ばしても問題ありませんが、一応原因なども書いておきます。
テーマに抜粋表示機能が付いている場合、この抜粋はthe_excerpt()によって出力されている事がほとんどです。
「抜粋」が作られる時は、まずget_the_content()で、そのままHTMLで出力できるエスケープ済みのテキストが取得されます。これを元にして指定の文字数に切り出し、抜粋が作られます。
エスケープって何?
HTMLタグで使用される”<”や”>”、”&”などが文字列の中に記述されている場合、そのままではHTMLタグの一部などとして扱われてしまうかもしれません。そこで、単なる文字列として扱うためにするのがエスケープです。HTMLでは特殊文字に置き換えます。
”<”は「<」⇒less thanの略
”>”は「>」⇒greater thanの略
”&”は「&」⇒ampersandの略
他にもたくさんありますが、こんな暗号のような文字列に置き換えます。
普通に<サボさん>と文字を表示したい場合でも、<サボさん>と書くわけです。
もちろん、<スイちゃん>でも同じです。
しつこいようですが、上の例のように「白バイ野郎 ジョン&パンチ」も、「白バイ野郎 ジョン&パンチ」です。。。
問題となるのは、抜粋の切り出し元のテキストが、すでに上のようにエスケープされている事です。
つまり「白バイ野郎 ジョン&パンチ」ではなく、「白バイ野郎 ジョン&パンチ」の先頭から何文字と数えて切り出されます。これが抜粋の末尾におかしな文字が出現する原因です。
&が表示されてしまった例
試しに抜粋文字数を13文字に設定してみると、下のように切り出されます。
出ました。はい。
「&」をエスケープした時の「&」を途中で切ってしまったんですね。元々の文字コードとして機能しなくなって、意図しない文字列になってしまいました。ちなみに抜粋の文字数を14文字にしてあげれば、きちんと「&」が表示されます。
このような事が様々な特殊文字で起きます。たまたま抜粋の末尾が文字コードをぶった切る位置に来た時だけなので、結構気づかずに運営しちゃったりします。変な文字を使わない場合も、ほとんど症状は出ないかもしれません。
ですが、バグっぽくてカッコ悪いです。なんとかしましょう。
抜粋末尾の壊れた特殊文字を削除するコード
方法は様々あると思います。テンプレートを書き換えてthe_excerptを使わないで出力しても良いと思います。正規表現でもできますね。
ですが今回は、抜粋に関するテーマのデフォルト機能(文字数変更や全文/抜粋の切替など)を損なわない形で対処したいと思います。せっかく付いている機能が効かなくなるのも嫌ですしね。
以下のコードをコピーして、使用中のテーマのfunctions.phpに貼り付けます。最終行で構いませんが、最終行に「?>」と記述された行がある場合は、これを消さないように注意して、その上に貼り付けて下さい。
1 2 3 4 5 6 7 8 9 10 |
/* 抜粋の末尾で分割された特殊文字が残るのを修正 */ function remove_broken_characters($text, $num_words, $more, $original_text){ $planeExcerpt=html_entity_decode(wp_strip_all_tags($original_text),ENT_QUOTES); if($num_words < mb_strlen($planeExcerpt)){ return htmlentities(mb_substr($planeExcerpt,0,$num_words),ENT_QUOTES).$more; }else{ return htmlentities(mb_substr($planeExcerpt,0,$num_words),ENT_QUOTES); } } add_filter('wp_trim_words','remove_broken_characters',9999,4); |
もし、抜粋文字数も合わせて設定したい場合は、下のコードをプラスします。150の部分は文字数です。適当に書き換えて下さい。
1 2 3 4 5 |
/* 抜粋文字数の設定 */ function new_excerpt_length(){ return 150; /* 数字が抜粋の文字数 */ } add_filter('excerpt_length','new_excerpt_length',9999); |
コードの解説
一応解説を付けておきますが、wp_trim_wordsというフィルターフックを利用しています。
このフックは、excerpt_moreとexcerpt_lengthフックに登録されたフィルター関数の結果を受け取った後、抜粋が完成する直前の、実際に切り出して組み上げる部分のフックです。
実際に何を実行しているかというと、エスケープされている記事の全文を、いったんエスケープしていない状態に戻して、指定文字数で抜粋を切り出します。その後で、再度エスケープして返しています。
「テーマのカスタマイザーで抜粋の文字数を変更している」という場合や、「functions.php内で、excerpt_moreフックを使って抜粋の末尾テキストをカスタマイズしている」という場合も、カスタマイズした内容は問題なく機能します。
※文字数についてはWP Multibyte Patchを利用していたり、改行が含まれていたりすると指定した文字数通りにピッタリいかないケースがあります。この辺の文字数の調整は、環境に合わせて適当な数字に増減して頂くという事で、お許しを…
最後に
うまく抜粋の末尾のゴミ文字が取り除けましたでしょうか。
最後の行の9999は関数の優先順位ですが、他のフィルター関数と干渉がある場合は適当な数字に変えて下さい。