未入力のブロックや空の段落を分岐する方法

全般

今回は、WordPressのGutenbergエディターの段落やブロックが「未入力」のとき、段落を削除したり要素のクラス名を変更する方法を紹介したい。

これにより、本文上で空の段落や空のラベル、セル、見出しなどを簡単に分岐することが出来る。

Gutenbergの「未入力のブロック」をなんとかしたい

今回の悩みは見出しの通り、「未入力のブロックをPHPコードで簡単になんとかできないものか?」ということだ。

ご存じの通り、WordPressはPHPで動いている。そして、CSSを使うことで簡単に装飾できる。なので、編集画面でHTMLを手打ちしたり自作したショートコードを使うことで、簡単にタグ名を変更したりクラス名を分岐することが出来る。もちろん、手描きなので空の段落だって自分で削除できる。

しかし、現行のGutenbergエディター、つまりブロックエディターは一筋縄ではいかない

Gutenbergのことを少し調べた人は理解しているはずだが、このブロックエディターと呼ばれるものは全てJavaScriptで動いている。つまり、今までのようにマニュアル操作でなんとかできるものではない。

スポンサーリンク

そして、今回行いたいことは、「記事編集ページと投稿記事ページで未入力のブロックの扱いを切り替える」という簡単な二通りの分岐だ。つまり、入力されたブロックはそのままに、未入力の段落やブロックを削除するか、クラス名を変更・追加してCSSを用いた装飾を容易にするか、ということ。

つまり、行いたいことは「有るか、無いか」の二通りの切り替えのみなので、わざわざJSを使ってプラグインを自作するといった面倒なことをする必要性は感じられない。PHPを使って、簡単に結果を分岐させたいのだ。

今回使用するもの

子テーマのfunctions.php

今回のカスタマイズはPHPコードを使うので、「子テーマのfunctions.php」だけでよい。なお、ファイルの場所は、管理者画面の左側サイドバー内に存在する「外観」の「テーマエディター」ページに存在している。

子テーマのものかどうかよく確認してから書き換えよう。

ブラウザーのデベロッパーツール

本当に空の段落が削除されているか、未入力のブロックのクラス名が変わっているのかを確認する必要がある。これを簡単に確認するために、ブラウザー備え付けのデベロッパーツールを使おう。

F12キーF12)を押すだけで簡単に呼び出すことが可能だ。

ページの要素の部分については、エレメント(Elementと書かれている部分で確認することが出来る。

空・空欄・未入力のブロックを分岐するカスタマイズ

それでは、WordPressにカスタマイズを施していこう。

今回紹介するPHPコードは、すべてコピペでOKだ。

空の段落を削除するPHPコード

「カスタムHTML」ブロックや「クラシック」ブロックを使った際に、レイアウト崩れの原因になる空の段落。

この勝手に挿入される「pタグ」を、投稿記事画面から削除したいときのコードになる。

PHPコード
// 空の段落を削除するコード
function mycus_remove_empty_p($string){
    $string = force_balance_tags($string);
    $empty = array('#<p>\s*+(<br\s*/*>)?\s*</p>#i');
    $delete = array('');
    return preg_replace($empty, $delete, $string);
}
add_filter('the_content', 'mycus_remove_empty_p', 20, 1);

上記のコードをコピペして保存しよう。

確認してみよう

では、本当に空の段落が消えたのか確認しよう。デベロッパーツールを開いて、ページのエレメントを見てみよう。

まず、こちらがPHPコードを入力する前のページだ。

上の画像では「空の段落のテスト(始まり)」と「空の段落のテスト(終わり)」に挟まれた空のpタグを確認することが出来る。


そして、こちらがPHPコードを入力して保存し、ブラウザを更新したページになる。

削除されていることが確認できるだろうか?

未入力のブロックのクラス名を変更するコード

次は、未入力のブロックのクラス名を変更するカスタマイズを行おう。

これを行うことで、たとえば、あるブロックに「h3タグ」が有る場合と無い場合でデザインを分けたりすることができる。

今回はシンプルに「mycus-empty」というクラス名を追加してみよう。追加するブロックは、Wordpressの引用ブロックだ。引用部分が未入力の場合を想定する。

PHPコード
// 引用ブロックの引用部分が未入力のとき、クラス名を変更するコード
function mycus_replace_empty_quote_block($content){
    $content = force_balance_tags($content);
    $empty = array('#<blockquote class="wp-block-quote"><p></p></blockquote>#i');
    $rename = array('<blockquote class="wp-block-quote"><p class="mycus-empty"></p></blockquote>');
    return preg_replace($empty, $rename, $content);
}
add_filter('the_content', 'mycus_replace_empty_quote_block', 20, 1);

上記のコードをコピペしよう。

確認してみよう

では、本当にクラス名が変わっているかどうか、確認してみよう。

まずは、PHPコードを入力する前の状態で、ふたつのブロックを見比べてみる。

このように、上は「引用部分」「引用元」が入力されており、下はそのどちらも未入力だ。

では、このふたつのブロックのエレメントを確認してみよう。

上の画像の青い部分が、未入力の引用部分だ。何も無い、が有るといった状態になっていることがわかるだろうか?


それでは、コードを入力して保存し、ブラウザを更新してもう一度確認してみよう。

class=”mycus-empty”」がpタグに追加されていることを確認できるだろうか?

このカスタマイズの意味

なぜ、未入力のブロックに新しいクラス名を追加したのか?

その理由は、「style.css」を使ったCSSのカスタマイズを行いやすくするためだ。

つまり、このようなコードを組むことが出来る。

/*入力済*/
.wp-block-quote p {}

/*未入力*/
.wp-block-quote p.mycus-empty {}

このように、クラス名の有無で装飾を分けることが出来るのだ。

もちろん、引用ブロックの場合は、その恩恵が分かりづらいかもしれない。しかし、表ブロックや、タイトルやラベルなどが存在するブロックのカスタマイズでは役に立つだろう。

発展:ブロックの中に変更したい要素が複数ある場合

場合によっては、ひとつのブロックの中で、ふたつ以上の要素のクラス名を書き換える必要があるかもしれない。例えば、タイトルタグとラベルタグ、タイトルタグとキャプションタグなど……。

こんな時は、先ほどのコードをこのように変えればよい。

PHPコード
// 「element-a」と「element-b」のクラス名を持つ要素が空欄の場合に、それぞれ「mycus-empty」を追加するコード
function mycus_replace_empty_block($content){
    $content = force_balance_tags($content);
    $empty = array('#<div calss="element-a"></div>#i', '#<label calss="element-b"></label>#i');
    $rename = array('<div calss="element-a mycus-empty"></div>', '<label calss="element-b mycus-empty"></label>');
    return preg_replace($empty, $rename, $content);
}
add_filter('the_content', 'mycus_replace_empty_block', 20, 1);

すこし雑な例だが、こういうことである。

この例では、「element-a」というクラス名を持つdiv要素と、「element-b」というクラス名を持つlabel要素のふたつが空欄の場合は、それぞれ「mycus-empty」というクラスが追加される。もちろん、どちらかが片一方の場合でもちゃんと機能する。

このように、複数の要素を一度に指定したい場合は、「array()」の中を半角のコンマで区切ればよい。つまり、「array(‘a’, ‘b’, ‘c’)」とする。もちろん、中に入れるパラメーターをアポストロフィーで括ることも忘れずに。

また、同じ数だけ指定したのなら、必ず同じ数だけ置き換えるようにしよう。それを忘れるとサイトがエラーを起こしてしまう。

今回のカスタマイズに出てきたもの

preg_replace();

この関数は「AをBに置き換えて返します」という命令を実行する。また、配列(array)を使うことによって、一度に複数のものを置き換えることが可能。気になるならこちらのサイトに詳しく書いてある。

なお、コードの組み立て方については、以前私が記事にした「サイト内検索の結果から特定の記事を除外する方法」に出てくる方法とほぼ変わらない。

指定する要素の書きかた

つまり、これはなんだ?という話である。

\s*+(<br\s*/*>)?\s*

この上記のコードに書かれている文字列の意味は、「空の改行」と「半角スペース」である。つまり、未入力のみならず、未入力に等しいと思われるものをすべて置き換えているという意味である。

なので、ただ未入力の要素を指定したいときは、別に付ける必要は無い。

なお、「全角スペース」は適用されない。

「#(ハッシュ)」記号を付ける意味

なぜ、置換する要素を指定するときに、両端に「#」と「#i」を付ける必要があるのか?ということ。

'#<p>\s*+(<br\s*/*>)?\s*</p>#i'

これは、「preg_replace();」が「PCRE関数」だからである。この関数群で使われる正規表現の記号のひとつが、ハッシュ記号ということ。気になったならこちらのサイトを見てみよう。

force_balance_tags();

これは、「指定された文字列の文章のバランスをとる」という命令を実行するWordPress専用の関数である。

つまり、preg_replace関数によって生じた段落の消滅やクラス名の変更も、force_balance_tags関数によって綺麗に改変されるということ。気になった場合はこちらに詳しく書いてある。


以上で、今回のカスタマイズに使用した関数などの説明を終える。

最後に

今回のカスタマイズで使用したものは一般的な関数ばかりなので、ちゃんとコピペしたのなら特に問題は起きない。

しかし、紹介したコードを編集して使うのであれば、入力ミスが無いか注意しよう。ハッシュ記号の付け忘れには十分注意してほしい。


今回は、未入力の要素の分岐についてのカスタマイズの解説を書き留めた。

この記事を書くことになった理由は、Cocoonのカスタマイズを行っている最中に、なんとかして未入力の要素を区別したかったからだ。

結果的に、いろいろ調べているうちに発見したこちらの記事のコードを流用することで、求めているカスタマイズを行うことが出来た。

もし、私と同じ問題を抱えている人の解決の手掛かりになれば嬉しい。