カテゴリー
ブログ

投稿のタイトルをメール件名にすると起きる文字化けを防ぐ

概要

メールの件名に get_the_title() 関数の返り値をそのまま用いると、この関数内で行われている、文章を読みやすくするための処理が文字化けを起こすことがあります。これを回避する方法を3つ考えました。

背景

LOTD(日替わりリスト)をメールで配信する際には、 リスト投稿のタイトルをそのままメールの件名にしてメーリングリストに送信しています。メーリングリストはその件名の頭に [今日のリスト] という文字列を付けて配信します。

ところが ‘-‘(半角マイナス)を含むリストが ‘–’ に変換されてしまっていました。

内容

get_the_title() 中のフィルターフック ‘the_title‘ にはいくつかデフォルトのフィルターがセットされています。その一つである wptexturize() が問題を起こしているとわかりました。

wptexturize() は文章を読みやすくするための変換を施します。変換の結果は Web ページ(HTML文書)として表示されることを想定しており、いくつかの文字は HTML エンティティに変換されています。その代表的なものが ‘-‘ の ‘–’ への変換でした。

‘–’(または ‘–’ )はいわゆるダッシュ記号で、’-‘(半角マイナス)より少し長めにデザインされているフォントが多いようです。

この文字化けを防ぐには、やり方が大きく3つあると考えました。

一つめは get_the_title() を使わず 投稿オブジェクトの post_title メンバをそのまま使うこと。

二つめは wptexturize() を無効化すること。無効化のニーズが高いせいか、そのためのフィルターフックも用意されています。次のようにすれば wptexturize() を通したくないときだけ無効化することが可能。

add_filter( 'run_wptexturize', '__return_false' );
$lotd_title = get_the_title( $lotd_post );
remove_filter( 'run_wptexturize', '__return_false' );

__return_false() は標準で用意されている関数で、文字通り return false; だけをしてくれます。

三つめは、 wptexturize() が HTML エンティティに変換した結果を戻す(HTML デコードする)こと。先の例でいえば、せっかく半角マイナスをダッシュに変換してくれたので、それを HTML デコードすれば読みやすくなった状態で渡せます。そのためにはこんなふうにすればよいはず。

$lotd_title = html_entity_decode( $lotd_title, ENT_COMPAT | ENT_HTML5, 'UTF-8' );
図:メール一覧画面。上がダッシュ、下が半角マイナス

実際にメーラー (GMail) での見え方を比較してみました。

図の上の行は3つめ、つまり wptexturize() の変換結果を生かしたやり方で送ったメールで、ダッシュが表示されています。

下は2つめ(と原理的には1つめ)、つまり変換なし。半角マイナスが表示されています。

こうしてみると、ダッシュのほうが読みやすい。wptexturize() がおせっかい機能にしか思えなかったので2つめのやりかたでいこうと思っていたのですが、実験結果を見て3つめでいくことにしました。

※追記: 通常のメール送信はこれでOKでしたが、LOTD を配信させているメーリングリストが件名中のダッシュ(enダッシュ)を扱えず、「?」に変換してしまう問題があることがわかりました。エックスサーバーのメーリングリストは fml を使っているようですが、件名にセットする文字コードの指定などはなく、解決できていません。そこで現在は1つめの解決策を適用中。