
自作のCitron WP Shortcodeを作成している時に、どうも wpautop() を通すとレイアウト崩れが起こる。正常に表示されないと言ったバグに遭遇し…。
解決方法を探すためにあれやこれやと試行錯誤し、無駄な時間を過ごしたので簡単にですが遭遇する記載例と、その回避策を併せて紹介したいと思います。
wpautop()
関数名を読み解くとwp auto pWordPress(wp)に自動的(auto)にPタグ(p)を付与。って感じでしょうか。
関数リファレンスの説明でも、二行以上にわたる改行があれば<p>…</p>タグでくくると書かれており、自動的に適応されるコンテンツは、投稿や固定ページの本文と抜粋などです。
Gutenbergに変わる前のクラシックエディターでのビジュアルとHTMLの切り替えで wpautop() が悪さをし、レイアウトが崩れる。HTMLタグが勝手に消えるなどでfunction.phpに機能を停止するコードを書き込んだ方も少なからず居るのではないでしょうか。
今回は wpautop() を有効にしている際に起きるバグ的なものを一つ紹介します。
バグが出る記載例

まずはバグが出る記述例を見てみましょう。
<!-- wpautop前 -->
<div>
<div>バグ有り</div>
</div>
<!-- wpautop後 -->
<div>
<div>バグ有り</div>
</p></div>
<!-- wpautop前 -->
<div>
<div>バグ有り2</div>
</div>
<!-- wpautop後 -->
<div>
<div>バグ有り2</div>
</p></div>
wpautop() を使う前のHTMLタグの記入例としては何もおかしい所はありませんよね?
でも wpautop() を通すと何故か余計な</p>タグが挿入されるだけでなく、綺麗に<p></p>のセットで記載されていないため構文エラーにもなっています。
レイアウトの観点からですと余計な改行が一つ最後に入る感じになります。
バグの解説

結論から言えば
</div>タグの閉じタグが連続で2回続く場合、その間に半角スペースやタブ(\t)を入れると</p>が挿入されます。
分かりやすく一行で記入してみます。
<!-- バグが出る -->
<div><div>バグ有り</div> </div>
<div><div>バグ有り</div> </div>
<!-- バグが出ない -->
<div><div>バグ無し</div></div>
<div><div>バグ無し</div></div>
この現象に合う方はコードをインデントで見やすく整形している人でしょう。
私もその例に漏れずインデントしながらコードを記載していたため遭遇しました。
<div class="a">
<div class="b">
<div class="c">バグ有り</div>
</div>
</div>
忘れた頃に見ても理解しやすいように、コードを分かりやすく書く上で欠かせないインデントなんですが、wpautopを使う場面では思わぬ落とし穴に落ちてしまいます。
またこの現象は半角スペースやタブ(\t)のみで全角スペースや改行などでは起きません。
以下の例は全て問題なく wpautop() が適応されます。
<!-----------------------------
半角スペース+文字
----------------------------->
<div><div>綺麗にPタグで閉じられる</div> あ</div>
<!-- wpautop()後 -->
<div>
<div>綺麗にPタグで閉じられる</div>
<p> あ</p></div>
<!-----------------------------
全角スペース
----------------------------->
<div><div>綺麗にPタグで閉じられる</div> </div>
<!-- wpautop()後 -->
<div>
<div>綺麗にPタグで閉じられる</div>
<p> </p></div>
<!-----------------------------
半角スペース+全角スペース
----------------------------->
<div><div>綺麗にPタグで閉じられる</div> </div>
<!-- wpautop()後 -->
<div>
<div>綺麗にPタグで閉じられる</div>
<p> </p></div>
<!-----------------------------
spanに空白スペース
----------------------------->
<div><span><span>spanは関係ない</span> </span></div>
<!-- wpautop()後 -->
<div><span><span>spanは関係ない</span> </span></div>
<!-----------------------------
改行のみを複数入れた場合
----------------------------->
<div><div>/p タグは入らない</div>
</div>
<!-- wpautop()後 -->
<div>
<div>/p タグは入らない</div>
</div>
インデントを行う方はタブ(\t)で行うか、半角スペース4つで行うケースが多く。
コードを綺麗に書く人を狙い撃ちしたかのようなバグなんですよね、これ…。
回避策

とりあえず原因が分かったので</div>が2回連続で続く場合は必ず半角の空白スペースとタブを入れないようにしましょう。
またこれはプラグインやテーマを作成する方だけが遭遇するバグではなく wpautop() が適応される部分(記事本文・抜粋など)でも起こる現象ですので、記事内でHTMLタグを記入する際には十分注意して下さい。
Gutenbergでの注意点

GutenbergでHTMLタグを直接書けるブロックは複数ありますが、特にショートコードのブロック内にてHTMLタグを使う場合には注意して下さい。
ここで記入されたテキストは自動的に wpautop() のフィルターを通しますのでバグに遭遇する確率が高くなります。
ショートコード内でdivを複数扱った装飾を行われる人って意外と多いと思うので注意して下さい。
当サイトで配布のショートコード使用について

私のサイトにて配布している記事装飾プラグインCitron WP Shortcode
URLが見つかりません。ショートコードが内包されている他のプラグインでもGutenbergのショートコードボックスで使用すると稀にレイアウト崩れが起こる可能性があります。
そもそも当サイトで配布している全てのプラグイン内で wpautop() を適切に使用しておりますので、ショートコードブロックを使うと二重に wpautop() のフィルターを適応することになるんですよね(^^;
ですので、ショートコードブロックで問題が発生した場合はカスタムHTMLブロックを使う様にして下さい。
カスタムHTMLブロックは wpautop() フィルターを通さず、書いた文章がそのままHTML出力されますので wpautop() を内部で使っているであろうショートコードは基本カスタムHTMLを使うべき。と覚えておくと良いでしょう。
おわりに

wpautop() は正規表現で自動的に<p>…</p>を挿入しているので、特殊なケースに遭遇した場合の例外処理が不十分なんでしょうね。
この機能を停止さえすれば今回紹介したバグには遭遇しませんが、停止すると困る機能でもあるため、上手に付き合っていくしかありませんね。
それにしてもインデントでコードを綺麗に書いている人だけ狙い撃ちにした様なバグなので、遭遇する記載例を見つけた際には脱力しましたよ。見つけるまで一日ずっと関係ないとこを修正したりなど試行錯誤してバグを探してましたから・・・。