WordPress 5.0 更新と wpautop 障害

たまにはタイムリーなネタを。Wordpressの5.0が遂にリリースされた。さすがにメジャーバージョンアップに当たるので、事前にソースとDBをバックアップしてから作業を始める。久々にサーバを覗いてみると、ファイルシステムとして使っているGlusterfsが片肺になってて、Split-brainしまくり。ここだけまだGlusterfsのバージョン上げてないからSplit-brainの対応が面倒なんだよね。。。IDCFが個人向けサービスやめるとか言ってるから、その移行の際にまたアーキテクチャ変えてみたいな。おっと、脱線。

Glusterfsの不具合を直したところで、wordpressの本体バージョンアップ以外の更新を全て済ます。バージョンアップ後にモジュール更新すると切り分けがややこしくなるからね。サーバ側でwordpressのコードをgit commitする。DBもmysqldumpで書き出しておく。これでバックアップはOKなのでいよいよバージョンアップ。いつも通り更新ページからバージョンアップを実行。やたら時間かかるので、しばらく放置して他のことをやる。忘れた頃に確認すると、バージョンアップが無事終わっていた。いいね。

一通り画面を見て回って問題ないことを確認する。いい意味でも悪い意味でも特に変わりなし。というか、今回のバージョンアップって何が目玉なんだろ。おもむろに新規投稿をしようとすると見慣れないエディタが。。。Gutenbergというらしい。新しいものを安直に忌避するのは嫌いなので、とりあえずしばらく使ってみる方向で。単調な段落の連続しかない自分の投稿なら、新旧どちらのエディタでも大して差がないし。パーマリンクがタイトルになっていないのが気になるけど直せない。とりあえずガチャガチャ書いて公開してみる。

公開されると、きちんと設定した通りのパーマリンクがアサインされる。確かに下書き中にタイトル変えるといちいちパーマリンク変更する必要があったからね。公開時にFIXするということで正しい仕様かも。何になるのかわからない不安はあるけど。公開された記事を見てみると、まったく改行がなく、すべての段落が結合された状態になっている。あれ、何だこれ。HTMLソースを見ても確かにpタグが入っていない。コードエディタで文章を確認すると、pタグ入っているんだけどな。どういうことだ?

過去の記事についてもDB上の文章を確認するとpタグが入っていない。にもかかわらず、実際に記事を表示するとpタグが含まれる。どうやらwordpressはpタグを自動補完してくれるようだ。ぐぐってみると、これはwpautopという機能みたい。pタグを自動補完するらしいけど、そもそもHTMLソースからpタグを削除してしまう処理もあるらしい。このpタグ自動削除を止めれば期待通りになるのかな。functions.phpに以下のコードを追加して、エディタによるpタグの自動削除を止めてみる。

function my_tiny_mce_before_init( $init_array ) {
    $init_array['valid_elements']          = '*[*]';     
    $init_array['extended_valid_elements'] = '*[*]';
    return $init_array;
}
add_filter( 'tiny_mce_before_init' , 'my_tiny_mce_before_init' );

残念ながら何も変わらず。とりあえずShift+Enterでbrタグを2つ入れれば、それらしく出来るけど、どうやったらpタグが入るんだろ。他のブログを見てみると、高度な設定から追加CSSクラスを指定するとタグが残ってくれるという。段落ブロックを選択して追加CSSクラスに『dummy』を指定してみる。これで公開すると、<p class=”dummy”>みたいな形でタグが入るようになった。これで見た目上は期待通りになったんだけど、全ブロックでいちいちクラスを指定するというのもちょっとなあ。

そして、最悪の問題に気が付く。トップページやカテゴリページなどにGutenbergによる新投稿が加わると、この一覧ページにおいてもpタグ自動補完が止まってしまって、一覧ページの段落サマリー機能が効かず、全文表示になってしまっていた。中には文中にpタグを持つものもあり、それがひどい崩れ方をして大変な状態に。投稿がwpautopを前提としたものと、それを無効化したものとが混在している状態に。これを直すには、すべての投稿にpタグを入れ直すか、全投稿に対してwpautopを有効化するか。

そもそもGurenbergで作成した記事からもpタグが消えることを鑑みれば、wordpress 5.0以降でもwpautopを前提とした仕様のように見える。にもかかわらず、何らかの事情でこれが無効になる。やむなくphpソースを見てみると、犯人は意外にも早く見つかった。wp-includes/blocks.php内で、とある条件下で有効になる以下のコードを発見。

        $priority = has_filter( 'the_content', 'wpautop' );
        if ( false !== $priority && doing_filter( 'the_content' ) && has_blocks( $content ) ) {
                remove_filter( 'the_content', 'wpautop', $priority );
                add_filter( 'the_content', '_restore_wpautop_hook', $priority + 1 );
        }

このコードのうち、remove_filter()の行をコメントアウトしてみると・・・pタグが自動補完されるようになった。こんなコードがあるとすると、将来的にはwpautopはdeprecatedになっていく恐れもあるが、現時点では機能してくれないとまともな表示にならないので有効化しておくことにする。コード直編というのは頂けないので、テーマ内にあるfunctions.phpに以下のコードを追加する。

add_filter("the_content", "wpautop", 0, 1);

これで過去記事の仕様をそのままに、wordpress 5.0のGutenbergを試せる状態となった。自分の環境ではGutenbergで編集しても相変わらずpタグは入らないが、wpautopがそれを補完してくれるので問題にならない状態だ。5.0.2ではGutenbergの諸々なbug fixが含まれるらしいので、また振る舞いに変化が現れるかもしれない。とはいえ、基本的にはwpautopをどう扱うかの問題なので、そこを注意していれば対応は可能なはず。一方でIDCFから引っ越す準備も進めなければいけない。次はGCPかなあ。

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)