WordPressのビジュアルエディタで「そのままHTMLを記述」して、そのままHTMLとして表示できるようにするプラグインを作ろうと思ったのですが…WordPressには不思議がいっぱい。
やりたいことーΣ(゚ロ゚)o゙
WordPressの「ビジュアルエディタ」で入力した文字列は、投稿(記事)を表示したときに、そのまま表示されます。
[html]<b>Σ(゚ロ゚)o゙</b>[/html]
と書いたら、
という感じで太文字で表示されるのでは無く、
と表示される、ということです。
普通に使っている人からすれば、当たり前なことですね(^-^;
んじゃ、自分で太文字(ボールド)とか指定したい時は?というと、「ビジュアル エディタ」から「テキスト エディタ」に切り替えて、直接HTMLを書きます。
この状態なら、
[html]<b>Σ(゚ロ゚)o゙</b>[/html]
と書いたら、
と表示されます。
自分は普段「ビジュアル エディタ」を使っているのですが、切り替えるのも結構面倒なのです。
じゃあ、「ビジュアルエディタのまま、直接HTML書けるといいんじゃないか!」とか考えてみるわけです。
(「面倒」とか「手を抜きたい」とかって、開発の原動力ですよね!Σ(゚ロ゚)o゙)
例えば、
[html decode=”true” wrap=”true”]こんにちはΣ(゚ロ゚)o゙
こんな感じで、
[direct]<b>Σ(゚ロ゚)o゙</b>[/direct]
とかやったら、<b>Σ(゚ロ゚)o゙</b>じゃなくて、太文字になったらいいよね!Σ(゚ロ゚)o゙[/html]
とか書いたら、
こんにちはΣ(゚ロ゚)o゙
こんな感じで、
Σ(゚ロ゚)o゙
とかやったら、<b>Σ(゚ロ゚)o゙</b>じゃなくて、太文字になったらいいよね!Σ(゚ロ゚)o゙ |
という結果になる想定です。
まあ、「ビジュアル エディタ」と「テキスト エディタ」を切り替えればいいんですけど、興味はもう「ラクしたい」というよりも、「作ってみたい」に移っていたりするので(^-^;
(そして、「出来上がったこと」に満足して使わないパターンになることも…。)
HTMLエスケープってなんだ?Σ(゚ロ゚)o゙
ビジュアルエディタでHTML記述に使う記号、たとえば < は < 、> は > などに置き換わり、不用意にHTMLタグとして動かないようになっています。
こういう感じにするのを「HTMLエスケープ処理」とかいいます。
| 文字 |
エスケープ後 |
| (空白) |
|
| < |
< |
| > |
> |
| & |
& |
| “ |
" |
表示するときは、この逆をするので、「<b>Σ(゚ロ゚)o゙</b>」とか書いても、「Σ(゚ロ゚)o゙」となっちゃわずに、「<b>Σ(゚ロ゚)o゙</b>」に置き換わってから保存されているので、表示されるときにはその逆をして、元々書いていた「<b>Σ(゚ロ゚)o゙</b>」と表示されていたわけです。
(「 」は「単なる半角スペース(空白)」では無いのですが、ここでは「(空白)」としておきます。Googleとかで検索すると詳しく解説しているサイトさんがあります。)
記事が格納されたDBテーブルを見たところ、 < と > 、 & はエスケープ(変換)されていますが、 ‘ とか “ とかはそのままみたいです。
では、逆エスケープしてみよう
使えそうな関数を調べようとした瞬間に、
「あれ、そういえば、エスケープの逆って何て言うんだろう?Σ(゚ロ゚)o゙(←無知)」
と、検索するキーワードが分からなくなってしまいました(^-^;
「逆エスケープ」とか「アンエスケープ」とかで良さそうです。多分。
「よく使う逆関数」というのがまとまってました。
[link url=”http://www.ateliee.com/archives/1314″]
関数名からすると「デコード」っていうのが良いのかな?
とりあえず、
- htmlspecialchars_decode
- html_entity_decode
この2つが候補となりました。
とりあえず、ちゃちゃっとプラグインを作ってみます。
[php mark=”15-16″ decode=”true”]<?php
/*
Plugin Name: Pz-DirectHTML
Plugin URI: https://popozure.info/20150816/8182
Description: ビジュアルエディタだってHTMLしたい
Version: 0.01
Author: poporon
Author URI: https://popozure.info
*/
class Pz_DirectHTML {
function __construct() {
add_shortcode( ‘direct’ , array($this, ‘Pz_DirectHTML_ShortCode’));
}
function Pz_DirectHTML_ShortCode($opt , $content = null) {
$content = htmlspecialchars_decode($content);
// $content = html_entity_decode($content);
return $content;
}
}
$pz_directhtml = new Pz_DirectHTML;[/php]
こんな感じで書いて、15~16行目のコメントを付けたり外したりしてみます。
とりあえず、深くは考えないで、両方で試してみます。
[html decode=”true” wrap=”true”][direct]<a href=”https://popozure.info/20150811/8104″><img src=”http://mailbox.conohawing.com/popozure/blog/wp-content/uploads/2015/08/poster-thumbnail1.jpg” />なつやすみ!</a>[/direct][/html]
とか書いたのを、関数に入れて出力してみます。
まずは「htmlspecialchars_decode」から。
画像もリンク先もダメになっています(^-^;
出力されているソースを見てみると、
| <a href=”https://popozure.info/20150811/8104″><img src=”http://mailbox.conohawing.com/popozure/blog/wp-content/uploads/2015/08/poster-thumbnail1.jpg” />なつやすみ!</a> |
という感じで、ダブルクォートのところが「”」と「″」になっています。
んー???Σ(゚ロ゚)o゙??
「html_entity_decode」を使ってみます。
画像もリンク先もダメになってます。
見た目は一緒ですが、出力されているソースを見てみると、ダブルクォートが全角の「閉じ」になっているようです。
上のやつの「”」と「″」がそのまま文字として表示されている感じです。
んー???Σ(゚ロ゚)o゙??
HTMLエンティティってなんだ?Σ(゚ロ゚)o゙
半角ダブルクォートで入力したつもりなのに、表示したら全角ダブルクォートだった。Σ(゚ロ゚)o゙
ということで、DBテーブルを確認。
データは「“」のまま格納されていました。
記事を表示させたものを「ソースを表示」で見てみると、ダブルクォートは「”」に置き換わって表示されています。
つまり、「記事中に “ を記述」→「DBには “ のまま格納」→「表示するときにWordPressが ” に置き換える」→「ブラウザがダブルクォート(右)として表示する」という動きをしているらしいです。
この「”」とかいう表記を「エンティティ文字」と呼ぶようです。
文字を文字そのものじゃなくて、「文字コードを表した文字列で表す」のが「エンティティ文字」という認識でいいのかな?
(ちょっとこの辺、不勉強です(^-^;)
さて、ショートコードで動くタイプのプラグイン(関数)へは、ショートコードに挟まれた本文が渡されますが、この時には既に「”」は「”」とか「″」に置き換わった状態のようです。
「htmlspecialchars_decode」は、「HTML特殊(エスケープ)文字」のみ戻すので、ダブルクォートは「”」「″」という文字のまま出力。
「html_entity_decode」は、「HTML特殊文字」と「HTMLエンティティ文字」を戻すので、「”」「″」はそれぞれ「ダブルクォート」に戻っているのですが、
…そっちじゃないんだなぁΣ(゚ロ゚)o゙
書式を整えてくれるformatting.php
DBに格納されている “ を、そのままエンティティ文字にするならば、# になると思うのですが、WordPressは ” に変換しているようです。
ユーザーとかが入力した “ をそのままHTMLとして出力したら、パラメータとして成立しちゃって…とか考えると、そういうのを防ぐための動きなのだと思うのですが…(^-^;
ダブルクォートが全角に置き換わってしまうのは有名なようで、対処方法とかもあちこちで書いてありました。
[link url=”http://blog.s-giken.net/173.html”]
この処理を行っているのが「/wp-includes/formatting.php」ということでした。
中身をさらっと見てみると、シングルクォート/ダブルクォートによる囲みを見つけると、「開けクォート(左)」と「閉じクォート(右)」に変換しているようです。
[html decode=”true” wrap=”true”]”こんにちはー(^-^)o”[/html]
↓
| 結果 |
 |
「XSS防止」的なやつかと思ったのですが、普通に文書としての「見栄え重視」の動きだったようです。
今回は記事全体のダブルクォートの表現について考えようと思っていないので、プラグインの中で何とかする方向で考えます。
そのまま置き換えてみる?
formatting.phpを見てみると、パターンによってダブルクォートの変換を行っているようです。
まずは、数字の直後の “ 。
[php start-line=”71″ decode=”true”] /* translators: double prime, for example in 9″ (nine inches) */
$double_prime = _x( ‘″’, ‘double prime’ );[/php]
コメントを見ると、「ダブルプライムへ変換。例.9″(9インチ)」ってことで、数字の直後は「インチ」を表すので「ダブル プライム(″)」に変換するよ、ということらしいです。
[php start-line=”156″ decode=”true”] // 9″ (double prime)
if ( ‘”‘ !== $double_prime ) {
$dynamic[ ‘/(?<=d)”/’ ] = $double_prime;
}[/php]
あとは、囲い。
2つで「組み」になっていそうなのは、「ダブルクォート(左)(“、“)」と「ダブルクォート(右)(”、”)」に置き換えているようです。
「"」「"」「"」となっていても、「“」(半角ダブルクォート)に置き換えてから上記の処理をするようです。(多分)
「」(バックスラッシュ、日本では円マーク)、「‘」(シングルクォート、アポストロフィー)、「&」(アンパサンド)なんかも置き換えを頑張ってくれているようです。
英語圏ではそもそも全角文字で入力する文化が無い(先入観)ので、入力は半角だけど、Unicodeとかではちゃんと区分けされたから表示はなるべく頑張ろう、っていう感じなのでしょうか。
とりあえず、ダブルクォート以外は興味が無いので…
コレデドウダーΣ(゚ロ゚)o゙
[php mark=”15″ decode=”true”]<?php
/*
Plugin Name: Pz-DirectHTML
Plugin URI: https://popozure.info/20150816/8182
Description: ビジュアルエディタだってHTMLしたい
Version: 0.01
Author: poporon
Author URI: https://popozure.info
*/
class Pz_DirectHTML {
function __construct() {
add_shortcode( ‘direct’ , array($this, ‘Pz_DirectHTML_ShortCode’));
}
function Pz_DirectHTML_ShortCode($opt , $content = null) {
$content = str_replace(array(‘“’, ‘”’, ‘″’), array(‘”‘, ‘”‘, ‘”‘ ),$content);
$content = html_entity_decode($content);
return $content;
}
}
$pz_directhtml = new Pz_DirectHTML;[/php]
↓
できたー!Σ(゚ロ゚)o゙
とりあえず、「“」「”」「″」を、いずれも「”」("に当たる半角ダブルクォート)に置き換えてみたところ、ちゃんと画像も表示されて、リンク先もちゃんと飛べるようです。
(ただし、意識して全角ダブルクォートを使ったものまで半角ダブルクォートに置き換わってしまうため、パラメータが途中で閉じてしまったり、HTMLタグとして変な動きをする可能性はあります。でも、WordPressの動きがこうなので仕方が無いです。)
できたっぽいのでチェックをしてみる
一応、こんなチェックもしてみます。
[html decode=”true” wrap=”true”][direct]<?php echo ‘ここがPHPとして動作してたらヤバいかも!?’; ?>[direct][/html]
↓
| 結果 |
| <?php echo ‘ここがPHPとして動作してたらヤバいかも!?’; ?> |
処理のタイミングを考えれば当然といえば当然ですが、PHPとしては動作しないで、HTMLタグも全部文字列として表示されました。
コメント欄で [[direct]] とか書いてみても、動作しないので、アクセスしてきた人が悪用することも出来なさそうです。
大丈夫そう、かな。
うん。Σ(゚ロ゚)o゙
ビジュアルエディタでもHTMLタグが直接書けるプラグインができましたΣ(゚ロ゚)o゙
…Σ(゚ロ゚)o゙
でも…Σ(゚ロ゚)o゙
そもそも何しようと思って、これ作ろうと思ったんだっけ…Σ(゚ロ゚;o゙(本気忘れ)
「実用」としては需要があるかは謎ですが、ダウンロードできるZipファイルを用意しましたので、研究用にでもどうぞ。
↓
[ZIPファイル]
※完成度は高く無いので、プラグイン公式ディレクトリに上げる予定はありません。
※GPL2に準拠するため、コードを改良して公式ディレクトリに上げていただいたりすることは差支えありません。
※使っている報告や、不具合など、当記事のコメント欄や、Twitter(@popozure)、TwitterのDM等で教えていただけると嬉しいです。
(2017/01/23追記)ある程度需要がありそうなので、公式プラグインディレクトリにて公開しました。「Pz-DirectHTML」で検索してインストールしてください。