さて、掲題の件ですが、ほぼ備忘録です。僕がまったく知らなかったために、けっこう時間かかったのですが、知ってる人は知ってるらしいですね。
さて、先日お仕事で大量の記事をインポートしていたのですが、終わったと思った後にiframeが全部消えているという事態が発生しました。
「なぜ?」と思ったのですが、WordPressの次のような仕様が原因だったようです。
- WordPressはタグの無害化にksesというライブラリ(wp-includes/kses.php)を利用している
- ksesはタグのリストと属性のリストを持ち、そこに挙げられていない要素は全部除去する機能がある
- WordPressはksesを投稿フォームやコメントフォームなど、いたるところで使っている
- シングルインストールの管理者およびマルチサイトのネットワーク管理者には
unfiltered_html
という権限があり、この権限を持つ者は上記のksesによるフィルタリングが適用されない
これ、Codexにも書いてあったんですね。これにより、次のような事態が発生します。
- iframeなどの特定のタグを管理者は入力できるが、投稿者は入力できない
- WordPress Importerなどを利用しているのが管理者でも、iframeなどの特定のタグは消える
では、どうすればいいのかというと、次のようなフィルターフックをかけます。
/** * 有効なタグのリストを追加する * * @param string $tags * @param string $context * * @return string */ add_filter('wp_kses_allowed_html', function( $tags, $context ){ switch( $context ){ case 'post': $tags['iframe'] = array( 'src' => true, 'width' => true, 'height' => true, 'id' => true, ); break; case 'comment': // コメントの場合 break; } return $tags; }, 10, 2);
一回 var_dump
して貰えばわかると思うのですが、$tagsは要素名をキーに、値として許可された属性名からなる配列を持ちます。なので、変なタグを入れたいなという場合は、こちらのリストを修正すればいいんですね。
デフォルトのタグリストはwp-includes/kses.phpを見るとわかります。
僕はrubyプラグインを出しているのですが、なんどか「動きません!」みたいなことを言われてどうしても再現できず、「ブラウザの問題じゃねーの?」などと思っていたのですが、これが原因だったっぽいですね。いつも管理者だから気づきませんでした。ほんとうにすまんかった。
なので、さっきアップデートしておきました -> WP-Yomigana
TinyMCEで消されないようにする
さて、物事を複雑にするのはですね、このタグのリストを追加する方法とは別に、TinyMCEというビジュアルエディタを動かしているJSもフィルタリングをかけるということなんですよ。
ksesが走るのは投稿を保存するときなのですが、それとは別に、ビジュアルエディタとhtml入力を切り替えるときにはTinyMCEのフィルタリングが走ります。
ここでも有効な要素として登録しておかないと消えてしまいます。このやり方は以前書いたWordPressのTinyMCEをチキチキにカスタマイズするという記事を参照してください。
こう考えると、iframeやrubyなどのタグをまともに入れられるようにするには、2箇所のフックが必要ってことですね。なるほどわからん。
思うに、unfiltered_html
って必要なんですかね。権限として。「特定のユーザーだけいろんなタグが入れられる」という事実にあまり意味がないような気が……
だって、たとえばかよわき投稿者がですよ、偉大なる管理者様に向かって、「管理者様、申し訳ございません、私のような下賤の者ではGoogle Mapを貼り付けることができませんでした。どうにか、私めの投稿にiframeを貼り付けていただけないでしょうか?」と頼んだとするじゃないですか。
で、かけまくもかしこく管理者様がiframeを貼ったところで、次に投稿者が投稿を保存したらiframe消えるんですよね。そうしたらまた投稿者が「カンリシャサマー」ですよね。なんなんですか、それ。中東の役所みたいじゃないですか。
コンテンツの入力を制限する使い方ができるぞ!
さて、文句ばっかり言ってもしょうがないので、この機能の有効な活用方法を考えてみましょう。
僕個人は文章を書いたり読んだりするのが好きで、テキスト・オリエンテッドな考え方を持っており、「そもそもサムネイルやアイキャッチをつけないとクリック率が上がらないという現実と戦わなきゃ!」というラジカルな考え方の持ち主なのですが、WordPressをCMSとして使っていると、「HTMLを入力できる人は入力していいよ!」という決着になることがあります。
たとえばあなたがGihubやJS Do itのようなサイトをWordPressで作っていて、「投稿を行う人がHTMLを入力できる」というのがそのコンテンツの核になるような場合ならばよいのですが、ほとんどの場合は折衷案として出ている結論だったりします。
僕が見たり運用してきた中で、次のような条件のいずれかが存在するとHTMLで入力することになりますね。
- 見栄えに対するこだわりは強いが、その見栄えを構造的に分解できるほどの設計力がない(ex. 綺麗なPSD出すけどレスポンシブデザインはできない)
- よくモジュール化されたデザインであっても、それをUIに落とし込む技術力がない(ex. TinyMCEのプラグインを作れない)
- 職能が分解されているにもかかわらず、調整が行われない(ex. ライターがどうしても金赤を使いたいといい、デザイナーがNoと言っているのに勝手に金赤を使う)
とはいえですね、僕にもそれを「技術力低いカスどもワロス」とバカにするつもりはなく、そういうことは往々にして起きうるんですよ。お金が足りないとか、人が足りないとか、時間が足りないとか、でもいまやりたい、回れよ地球とか。
で、サイトが成功したとしましょうよ。そこで、CEOがみんなにこうやって伝えるんですよ。
これまで我々はクソのようなインラインCSSを書いてきた。しかし、そろそろよく構造化されてレスポンシブなデザインに変えるべきだ。
それにより、我々のサイトを訪れる月間ユニークユーザー200万人は、閲覧PV数を平均で20増やすだろう。そうすれば、我が社の収益は15%アップする。この15%は私たちが新しいことにチャレンジするための原資だ。未来への糧だ。みんなもこの新しいコンテンツ制作フローを守り、一緒に未来へと進んで欲しい。
そうするとですね、みんな「ハイ!」って言うんですよ。で、その日の夜の飲み会で「今日の社長ヤバかったよね〜超熱かった」とか言うんですよ。それなのに、翌日、style属性にインラインCSSを書くんですよ。「俺の作った超面白コンテンツを彩るstyle=”font-size: 60px; color: red;”を喰らえ!」つってね。
なんでこんな悪夢のようなことが起きるかというと、入力できるからなんですね。入力できるのがいけないんですよ。はっきりいって、コンテンツ入力する奴なんて、全員狂ってるか敵かぐらいに思った方がいいですよ。ほんとは味方なんですよ? 知ってますよ? でも、親の仇ぐらいに思ってちょうどいいぐらいなんですよ。
はい、長くなりました。
要するに、style属性が入力できなければいいんですよね。そのためには、こうします。
/** * 有効なタグのリストを追加する * * @param string $tags * @param string $context * * @return string */ add_filter('wp_kses_allowed_html', function( $tags, $context ){ switch( $context ){ case 'post': foreach( $tags as $tag_name => $attrs ){ if( isset($attrs['style']) ){ unset($tags[$tag_name]['style']); } } break; case 'comment': // コメントの場合 break; } return $tags; }, 10, 2);
これでstyle属性を入力しても、保存時に削除できるようになりました。もっとも、これをやるとテキストの中央寄せとか、色付けは一切動かなくなるですけどね。
あとですね、ビジュアルエディタって、HTMLとテキストで切り替えできるじゃないですか。これをオフにしてしまえばいいんですよ。
/** * エディターの設定を上書き */ add_filter('wp_editor_settings', function($settings, $editor_id){ // Queck tagsをオフにすると、 // 切り替えボタンがなくなる $settings['quicktags'] = false; return $settings; }, 10, 2);
こうすれば、style属性を書こうとも思えなくなるので、ますます減りますね。
他にもいろいろ調整しなければいけないところはありますが、「ビジュアルエディターしか使えない」というのはHTML入力厨やbr厨にダメージを与えるためにはうってつけの手段ですよ。
管理者がたくさんいたら意味ないですけど、それはまた別の問題なので。そりゃ誰だって、いままで管理者だったのにいきなり投稿者になったらいい気はしないですよ。たとえそれがWordPressのユーザー権限であったとしてもね。
というわけで、長くなったのでここらへんで。CMSは人と人とが魂となってぶつかり合う人間交差点。「つちよし」の入力やおぞましい背景色、異常に選択肢が多いクソプルダウンが今日も火花を散らしている。終わり。
[429] [429] Client error: `POST https://webservices.amazon.co.jp/paapi5/getitems` resulted in a `429 Too Many Requests` response: {"__type":"com.amazon.paapi5#TooManyRequestsException","Errors":[{"Code":"TooManyRequests","Message":"The request was de (truncated...)