htmlヘルパーlinkはリンク文字列をHTMLエンティティ化する
想定外。
Sanitize::html()でエンティティ化した文言を、$html->linkでリンクすると、リンク文字列がアンエスケープされず、エンティティのまま表示されました。
正(ホームで名前表示@文言リンクなし) <i>italic</i>(+-"1") 誤(一覧で名前表示@文言リンクあり) <i>italic</i>(+-"1")
これは$html->linkのデフォルト挙動で「aタグ内の文字列はHTMLエンティティ化する」のが原因でした。
つまり、$html->linkをデフォルトの引数設定だけで使うと、「画像リンク」とかは作成できないんだよ、という事を肝に銘じつつ。
htmlヘルパーをどこまで使うか、考え中です・・・・。
linkメソッドの中身を見て原因追究。第5引数の
$escapeTitle = true -> false
指定で解決しそうなのですが・・・
cake/libs/view/helpers/html.php
function link($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true) { (中略) if ($escapeTitle === true) { $title = h($title); } elseif (is_string($escapeTitle)) { $title = htmlentities($title, ENT_QUOTES, $escapeTitle); }
他の引数次第で $escapeTitleがデフォルトの true以外の値に書き換わるケースもありますが、
通常の設定なら
if ($escapeTitle === true) { $title = h($title);
を通る。
function h()は、cakePHP独自のhtmlspecialchars拡張(?)
cake/basic.php
function h($text, $charset = null) { if (is_array($text)) { return array_map('h', $text); } if (empty($charset)) { $charset = Configure::read('App.encoding'); } if (empty($charset)) { $charset = 'UTF-8'; } return htmlspecialchars($text, ENT_QUOTES, $charset); }
さらに、HTMLエンティティされたままのリンク部分のソースを見ると
&lt;i&gt;italic&lt;/i&gt;&#40;&#43;&#45;&quot;1&quot;&#41;
なので、
& → &
に変換されてるのが原因。
ということで、$escapeTitle = false の指定で解決!
・・・・とは、言い切れず。。。
- 今後のビュー全体で、「この変数はHTMLエンティティ化してるかどうか」を判断して第5引数まで指定するのか?
・・・そういう方法も、ありですが。
- htmlヘルパー使うのやめる?
考え中です。