この記事をおすすめしたい人
- WordPressのテーマを自分でいじろうとしている人
- WordPressが出力する<head>の「 />」が気になってしょうがない人
- つまりオレ
前回の記事でWordPressの<head>を舐め回すように見たわけですが、その中でちょっと思い出したことがあります。
コレ↓。
<link rel='dns-prefetch' href='//s.w.org' />
最後の「 />」の部分です。
今日はこれが何なのかをお話しして、最後はこれを取り除くところまでやっていきたいと思います!
WordPressの上でな!
あ、WordPressの上でいいんだった。
このページの目次
「 />」はXHTMLにおける終了タグ
例えば「<br>」タグ。
みなさんこれどう書きますか?
「<br />」こう書く人がいると思うんですよね。
これは「<br></br>」みたいな感じでタグを閉じるための書き方です。
でも<br>は間に何も入らないので「<br />」、みたいな?
先ほどの<link>もこれと同様です。
これはXHTMLの書き方で、HTMLの主流が
- HTML4
- XHTML 1.0
- HTML5
と移り変わっていったため、今もこのXHTMLの書き方が残っているのです。
その辺の事情を考慮して、HTML5では「<br />」のような書き方も文法エラーにはなりません。
文法的に正しかろうがどうしても気になるンダよ!
見てくださいコレ。
何ですかコレは?
なんかやたら不格好だし、バランスも悪いし、収まりも悪い。
何よりね、コレ、
閉じるんじゃなくて、むしろ開いてませんか?
そりゃ僕もXHTMLの時には意気揚々と後ろにスラッシュ付けてましたよ?
でも今はHTML5の時代です。
昔を引きずるのは女性のことだけで十分。
何よりW3Cのサイトを見ると、
Start tag: required End tag: empty
終了タグは「empty」と書いてあるんですよ。
<div>タグなんかはちゃんと「End tag: required」となっています。
W3Cが付けなくていいと言ってるのに、なぜわざわざ付けるのか、コレガワカラナイ。
例えそれがソース確認しないと見えない<head>の中だろうが、自分が書いてる部分じゃなかろうが、僕はこんなの耐えられません。
それに引き換え、見てくださいコレ。
どうです?かっこいいでしょ。
バランスも収まりもいいし、スタイリッシュだし、こっちの方がちゃんと閉じてる感もあります。
あとね、下位互換である「 />」の方が入力数が多いのがめっちゃ気になりませんか?
今と逆で、XHTMLが「<br>」、HTMLが「<br />」なら僕は前者を選択したかもしれない。
ですが「<br>」と書くべきところを、わざわざ一昔前のXHTMLに合わせて「<br />」と書き足すんですよ?
意味が分かりません。
というわけで!
こんなしょーもない理由から、WordPressが出力するXHTML表記のタグをHTML形式に戻す方法を考えてみます。
WordPressのソースを書き換えてみる
WordPressのソースをいじって最初のこの↓コードを書き換えてみようと思います。
<link rel='dns-prefetch' href='//s.w.org' />
WordPressのソース量は膨大なので処理順に追っていくと日が暮れますが、「dns-prefetch」でgrepかけるとすぐに見つかりました。
<link>タグの出力は、WordPressをインストールした場所にある「wp-includes」フォルダ内の「general-template.php」で行われています。
Ver.5.4.2だと3278行目でした。
echo "<link $html />\n";
お前が犯人かいっ!
というわけで修正↓。
echo "<link $html>\n";
そして出力↓。
<link rel='dns-prefetch' href='//s.w.org'>
無事にHTML式になりました。
ところがこれには大きな問題が…。
書き換え箇所が多い
「general-template.php」内で「 />」で検索してみると28箇所もありました。
一括で置換してもいいんですが、WordPressのコア部分を触っているのですから一応コードの内容を確認しておいた方がいいでしょう。
さらには「 />」を出力しているコードが「general-template.php」の中だけとは限りません。
WordPressインストールフォルダ内をgrepかけて調べないといけないかもしれません。
作業量…。
WordPressが更新されたらどうするの?
大問題です。
アップデートが入るとせっかく書き換えたソースが元の書き方に戻されてしまいます。
しかもWordPressはけっこうな頻度でバージョンアップします。
バージョンアップのたびにこれやるの?
そんなアホな。
再修正し忘れや一部修正漏れなどを考えると、メンテナンス性の面でこのやり方はありえません。
wp_head()の出力内容をバッファリングする
バッファリングというのは本来であれば出力していた文字列を、いったんバッファに格納して変数として捕まえてしまう方法です。
詳しくはこの辺りを。
バッファリングでwp_head()の内容を変数として捕まえて、それを正規表現で書き換えた後に再出力するというアプローチです。
まずはバッファリング
functions.php内に以下のコードを追加します。 関数名はwp_head_plus()としています。
function wp_head_plus() {
//バッファリング開始
ob_start();
//<head>の中身の出力
wp_head();
//バッファの内容を変数に格納
$head = ob_get_contents();
//バッファリング解除
ob_end_clean();
//ここに正規表現を挟む
//バッファ内容を出力
echo $head;
}
wp_head()はそのままでは文字を出力する関数ですが、バッファリングしているのでその文字列は出力されずにいったんバッファへ。
その後、ob_get_contents()でその内容を変数へ格納しています。
このコードではまだ処理層がないので、実行するとwp_head()の中身がそのまま出力されます。
閉じタグを消す正規表現を考える
考えられそうな閉じタグのパターンは次の6種類。
- <link />
- <link/>
- <link rel='dns-prefetch' />
- <link rel='dns-prefetch'/>
- <link rel="dns-prefetch" />
- <link rel="dns-prefetch"/>
なので正規表現はこんな↓感じに。
$head = preg_replace("/([a-z]|'|\") *\/>/i", "$1>", $head);
けっこう手抜きの正規表現なので、気になる人は「HTMLタグ 正規表現」とかできっちりしたのを使うといいと思います。
関数全体はこう↓なります。
function wp_head_plus() {
//バッファリング開始
ob_start();
//<head>の中身の出力
wp_head();
//バッファの内容を変数に格納
$head = ob_get_contents();
//バッファリング解除
ob_end_clean();
//正規表現でHTML形式に変換
$head = preg_replace("/([a-z]|'|\") *\/>/i", "$1>", $head);
//バッファ内容を出力
echo $head;
}
あとはheader.phpにあるwp_head()を「wp_head_plus()」に置き換えるだけです。
wp_head_plus()の実行結果
まずはwp_head()の出力だとこれだけのXHTML式のタグが見つかりました。
<link rel='dns-prefetch' href='//s.w.org' />
<link rel="alternate" type="application/rss+xml" title="(略)" href="(略)" />
<link rel='stylesheet' id='wp-block-library-css' href='(略)' type='text/css' media='all' />
<link rel='https://api.w.org/' href='(略)' />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="(略)" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="(略)" />
<link rel='prev' title='old test' href='(略)' />
<link rel='next' title='test' href='(略)' />
<meta name="generator" content="WordPress 5.4.2" />
<link rel="canonical" href="(略)" />
<link rel='shortlink' href='(略)' />
<link rel="alternate" type="application/json+oembed" href="(略)" />
<link rel="alternate" type="text/xml+oembed" href="(略)" />
wp_head_plus()で実行するとこう。
<link rel='dns-prefetch' href='//s.w.org'>
<link rel="alternate" type="application/rss+xml" title="(略)" href="(略)">
<link rel='stylesheet' id='wp-block-library-css' href='(略)' type='text/css' media='all'>
<link rel='https://api.w.org/' href='(略)'>
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="(略)">
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="(略)">
<link rel='prev' title='old test' href='(略)'>
<link rel='next' title='test' href='(略)'>
<meta name="generator" content="WordPress 5.4.2">
<link rel="canonical" href="(略)">
<link rel='shortlink' href='(略)'>
<link rel="alternate" type="application/json+oembed" href="(略)">
<link rel="alternate" type="text/xml+oembed" href="(略)">
正規表現は手抜きでしたが、無事に全てのタグがHTML式に変換されてますね。
よい!
バッファリングは他の目的にも応用できる
wp_head()の出力内容を文字列として捕まえてしまうので、この中身に対してナニカ処理したい場合にはとても有効です。
例えば揃っていないインデントを削除したい場合。
例えば<head>内にremove_action()での消し方が分からないタグが入ってしまっている時。
他にも、the_content(これはget_the_content/$post->post_contentで十分)やwp_footer()の中身を書き換えたい場合など。
力業での書き換えなのであまりスマートではないですが、強引に書き換えられるのでけっこう有用です。
あとはショートコードの中身が多い場合にも便利ですね。
まとめ
WordPressが出力する<head>内のXHTML形式タグをHTML式に変換するには、まずfunctions.phpに以下のコードを追加。
function wp_head_plus() {
//バッファリング開始
ob_start();
//<head>の中身の出力
wp_head();
//バッファの内容を変数に格納
$head = ob_get_contents();
//バッファリング解除
ob_end_clean();
//正規表現でHTML形式に変換
$head = preg_replace("/([a-z]|'|\") *\/>/i", "$1>", $head);
//バッファ内容を出力
echo $head;
}
あとはheader.phpにあるwp_head();を「wp_head_plus();」に置き換えるだけです。
こんなの需要あるのか!?
以上、WordPressからお届けしました!