投稿者「ロコモコ堂 フルタ」のアーカイブ

WordPressで「エラー: 予期しない出力により Cookies がブロックされました」が出た時の対処法

「エラー: 予期しない出力により Cookies がブロックされました」は、よくあるログイントラブルとは違います。

WordPressサイトの管理画面にログインしようとして、出来ない事が有ります。

ほとんどの場合は、

  1. 使っているブラウザから、該当Cookie(そのWordPressサイトのドメイン名)を削除する
  2. ‘wp-admin’ の代わりに ‘wp-login.php’ を使う
  3. wp-config.phpwp-config.phpにdefine( ‘RELOCATE’, true ); か
    define(‘WP_HOME’,’変更前アドレス’); と
    define(‘WP_SITEURL’,’変更前アドレス’); を追記
  4. プラグイン名を一時的に変えて、1つずつ元の名前に戻していきながら原因探し

バズ部 – WordPressのログイン方法とログインできない場合の解決法 で詳しく説明されています。)

で解決するわけですが、こんなログイン画面が表示されたら
管理画面にログイン出来ない上記の方法では解決出来ません。
これが表示された時は、ほとんどの場合、サーバが ‘HTTPレスポンスヘッダー‘ 情報を送り出す前にhtmlが出力されるエラーが発生しています。

症状の確認 – debug.logを出力し、チェックします。

それを確認する為にftpクライアントでWordPressディレクトリに入り、WordPressディレクトリ直下の ‘wp-config.php‘ をeditorで開いてやります。
そして80〜90行あたりにある

と書き換えてやります。
これはブラウザにエラーメッセージを表示させずに、’debug.log’ に書き出し、’/wp-content/’ に保存させるコードです。
(詳しくは、wp-login.phpのデバッグ忘れ(WordPressのデバッグ方法)をご覧下さい。)

その後、問題のログインページを再呼込みします。
ftpクライアントでWordPressサイトの ‘/wp-content/’ に ‘debug.log’ が生成されている筈ですので、Macなら ‘コンソール’ (Windowsなら ‘イベントビューア’ でいいのかな?)で開いてみます。

すると

とか

のログが書き込まれていると思います。

「ヘッダー情報を変更する事は出来ません – /path/hogehoge/wp-login.phpの403行で、(最初の例では)/path/hogehoge/wp-config.phpの1行目 (2番目の例では)/path/hogehoge/wp-content/themes/hogehoge/functions.phpの1行目によってヘッダーは既に送信されています。」
と言ってきてるんですね。

‘HTTPレスポンスヘッダー’ 情報は何よりも先に送り出す事になっているので、html(’HTTPレスポンスボディー’)が送り出された時点でヘッダーとは見なされなくなります。
config.phpやfunctions.phpの1行目で何か(文字・半角全角スペース・改行等制御文字など)が送信され、それがhtmlだと見なされて、実際のヘッダー情報は不正な変更と判断され、エラーとなるんですね。
PHPのError messageやdebug.logは、割と原因が判り易いので助かります。

config.phpやfunctions.phpの1行目は

とならないといけないのですが、
冒頭に半角スペースが入って気がつかず

としたり、1行目を改行して

となっている事があります。

これは ‘<?php‘より前の部分だけでなく、 最後の ‘?>‘ より後に文字(空白や制御文字も含む)が入っていても、’Cannot modify header information’ のエラーとなりますし、場合によっては ‘<?php‘ と ‘?>‘ の間に不必要な改行とスペースなどが入っていても起きます。

これはwp-config.phpやfunctions.phpだけでなく、wp-login.phpやプラグインのphpファイルで起きる事も有ります。

さらにややこしい事に、ファイル保存時のエンコードのタイプによって、起きる事も有ります。
WordPressのphpファイルの場合、エンコードは ‘UTF-8’ にするんですが、この ‘UTF-8’ には ‘BOM付き’ があり、これでエンコードをすると、ファイルのテキストの前に符号化の種類の判別コードが付き、 それが文字と誤認されるので、’<?php‘ の前に文字が有るということで、’Cannot modify header information’ のエラーとなります。

BOM(byte order mark)とはなにか?

ボムと呼び、データに使われている文字コードがUnicodeである事や、1と0で表されている文字データを、どのような規則で1文字ずつに分割するか( ‘endianness’ とか ‘byte order’ というやつ)を、テキストデータ部の前に付ける数バイトのデータの事です。

Unicodeは世界中の文字を扱える事を前提に考案されていますが、それ迄にASCIIやShift-JISやJIS、EUC-JPなど数々の文字コードが入り交じって使われたいたので、「文字はUnicodeである」と言う事と、多くの種類に分かれている1文字を決める為のバイトの分割方法を明示しなければいけなかった為、付けられる様になったものです。

UnicodeはUTF-8以外にUTF-7、UTF-16、UTF-16BE、UTF-16LE、UTF-32、UTF-32BE、UTF-LEなど何種類も有りますが、UTF-8ではBOMが付くとプログラムが正常に処理出来なくなる事が有り、データベースやメモリにロードするデータ等は、普通BOMでエンコードしません。

WordPressや他のPHPのWebプログラムでも、‘UTF-8 BOM無し‘(単に ‘UTF-8‘ 又は ‘UTF-8N‘ と表示)を使います。

「エラー: 予期しない出力により Cookies がブロックされました」の解決方法

解決方法は、

  1. まずwp-config.phpの
     

    と書き換えて、保存。その後、問題のログインページを再呼込みし、’/wp-content/debug.log’ を確認。
  2. ‘PHP Warning: Cannot modify header information’ の記述が有れば、その後の
    ‘headers already sent by (output started at’ 以降にかかれているのファイルの行と前後に不正な文字・スペース・改行などが無いか調べる。
  3. 問題が無ければ、wp-config.phpと、使っているテーマのfunctions.phpで ‘<?php’ が1行目の冒頭に有る事を確認。
  4. 問題が無ければ、wp-config.phpとfunctions.phpに ‘?>’ が有れば、その後に文字・スペース・改行などが無い事を確認。
  5. 問題が無ければ、wp-config.phpとfunctions.phpを ‘UTF-8 BOM無し’ で保存しなおす。
  6. まだログイン画面のエラーメッセージが消えない場合、WordPressディレクトリ直下のwp-login.phpとindex.phpで ‘<?php’ 以前と ‘?>’ 以後を確認。
  7. 問題が無ければ、wp-login.phpとindex.phpを ‘UTF-8 BOM無し’ で保存しなおす。
  8. まだログイン画面のエラーメッセージが消えない場合、プラグインのphpファイルで ‘‘ 以後を確認。
  9. 問題が無ければ、プラグインのphpファイルを ‘UTF-8 BOM無し’ で保存しなおす。

となります。
しかしこれでも解決出来ない場合は、最終手段となります。

‘php.ini’ の ‘output_buffering’ の設定を ‘on’ にする

‘php.ini’ の ‘output_buffering‘ は、ディフォルトでは ‘off’ ですが、それを ‘on‘ にします。

するとWordPressのログイン画面に「エラー: 予期しない出力により Cookies がブロックされした」のエラーメッセージは出なくなり、ログイン出来る様になります。

output_buffering‘ を ‘on‘ にすると、’HTTPレスポンスボディー(つまりhtml部分)’ がバッファーリングされ、先に ‘HTTPレスポンスヘッダー(つまりヘッダー部分)’ が送り出されるので、エラーが起きなくなるのです。

<?php‘ の前に半角スペースを入れていたり、’?>‘ の後に改行を入れていたり、保存時のエンコードをBOM付きでしていたり、以外と気が付かないものです。
気が付き難いだけに、原因究明にも手こずったりします。
ご注意下さい。

WordPressデフォルトテーマのSEO – h1タグの数をチェック

WordPressサイトを作る場合、Wordpressdデフォルトのテーマを元に、子テーマを作成して使う事も多いと思います。
WordpressデフォルトテーマはWordPressの純正だから間違いないと思うんですよね。
でも、W3Cの仕様に合っているかチェックすると、カスタマイズしていない部分でErrorやWarningが表示されるんですよ。

W3C – Markup Validation Service

ErrorやWarningには無意味な終了タグの存在なども有りますが、SEO的にまずいのは、h1タグが複数箇所で使われているテーマが有る事でしょう。
例えばデフォルトテーマのtwenty twelveを使うと、次の様な ‘Warning’ が出ます。

warning h1 as a top-level heading only

「トップレベルの見出しとしてのみ、h1要素の使用する様に検討してください。」と注意されるわけです。
h1タグはトップレベルの見出しに1カ所のみ使うと言うのは、SEOでも基本なんですよね?

HTML5になってsection要素やarticle要素ごとにh1タグを置ける様にはなっていますが、Bing Webマスターツールでも修正する様に言ってきますので、h1タグは、まだページに1カ所と考えておいた方が良いと思います。

WordPressのデフォルトテーマのh1要素の数と位置を調べてみる

そこで簡単な投稿ページを作成し、WordPressのデフォルトテーマで表示させて、使われているh1要素の数と位置を調べてみます。

実験ページはこんなの

実験ページ
調べてみるデフォルトテーマは

  • Twenty ten
  • Twenty Eleven
  • Twenty Twelve
  • Twenty Thirteen
  • Twenty Fourteen
  • Twenty Fifteen
  • Twenty Sixteen

の7テーマです。

古いデフォルトテーマでは、h1要素が複数有ります。

それぞれのテーマのh1要素の数は、

Twenty ten 1ケ所
投稿タイトルのみ使用
Twenty Eleven 2ケ所
header内のサイトタイトルと
投稿タイトルで使用
Twenty Twelve 2ケ所
header内のサイトタイトルと
投稿タイトルで使用
Twenty Thirteen 2ケ所
header内のサイトタイトルと
投稿タイトルで使用
Twenty Fourteen 7ケ所
投稿タイトル・サイドカラムの各ウィジェットでも使用
Twenty Fifteen 1ケ所
投稿タイトルのみ使用
Twenty Sixteen 1ケ所
投稿タイトルのみ使用

となっています。

‘Twenty ten’ では1カ所だったh1要素が、 ‘Twenty Eleven’ 、 ‘Twenty Twelve’ 、 ‘Twenty Thirteen’ 、 ‘Twenty Fourteen’ では投稿タイトルもh1要素になっていますし、 ‘Twenty Fourteen’ に至っては、サイドカラムの「最近の投稿」「アーカイブ」「カテゴリー」といったウィジェットのタイトル部分迄h1要素になっています。

‘Twenty ten’

‘Twenty Eleven’

‘Twenty Twelve’

‘Twenty Thirteen’

‘Twenty Fourteen’

‘Twenty Fifteen’

‘Twenty Sixteen’

‘Twenty ten’ で1ケ所だったh1要素は、’Twenty Eleven’ 、 ‘Twenty Twelve’ 、 ‘Twenty Thirteen’ 、 ‘Twenty Fourteen’で増えたのはhtml5の書式に合わせたからでしょうか。
ずいぶん前からWordPressはSEOに強いと言われていますが、h1要素だけ見た場合、それが言えるのは ‘Twenty Sixteen’ を含め ’Twenty Fifteen’ 以降になるんじゃないでしょうか?

投稿記事内のh2・h3・h4要素のタグ名変更も必要なんです。

しかし’Twenty Fifteen’ や ‘Twenty Sixteen’ が良いと言っても、投稿タイトルがh1要素として表示されるテーマで投稿をしていたサイトは、簡単にはテーマを変更できません。
投稿テーマがh1要素がh2要素になった分、h2要素の中にh2要素が配置されない様に、投稿記事内のh2要素をh3要素に、h3要素をh4要素にと修正してやらなければいけません。今迄の投稿を全てチェックして修正すると言うのは、かなりの覚悟が必要です(私がそうでした)。

信頼のブランドも、自分の目で確認する事が必要なのですね。

WordPressのテーマ ‘GONZO’ を使ってみた。

いつもはお客様の要望に合わせ、WordPressサイトのテーマをオリジナルで作成しているのですが、久々に有料テーマを使った仕事をやらせていただきました。
GONZO‘ を使ったサイトリニューアルです。

GONZO-screenshot

GONZO‘ はシンプルなグリッドデザインで、派手さは無いですが今のデザインですね。
お客さんの希望で使う事になりましたが、私もこのデザイン、好きです。

自動的にPC・スマホ・タブレットそれぞれに最適なレイアウトを取るレスポンシブと言うのが一番の売りになっていますから、予めcssで320px・375px・414px・480px・667px・768px・1024pxのディスプレイ幅のレイアウトが用意されています。色々なスマホやタブレットに最適なレイアウトで表示してくれるので、投稿した記事も見易くなります。

制作者の立場からしたら、もの凄く楽チンです。いちいちエミュレーターを使ってレイアウト確認をしながらサイトを作成していくあの労力と時間を思えば、東京〜大阪間をてくてく歩いていたのが、新幹線にでも乗って、一気に東京から大阪に移動したかの様な気分です。
ブラウザから送られたリクエストヘッダーのUser-Agentを調べて分岐させ、スマホは別に作成したjQuery Mobile用テーマで表示、なんてやってた頃を思い出したくなくなりますね。

サイトのカスタマイズで要望の多い、同じカテゴリーの過去記事を投稿記事の下部などへブログロールで表示させるのも、投稿記事の編集ページで5種類のレイアウトから選んで表示させたりも出来ます。

カテゴリーのブログロール挿入

ここの、 ‘m’ ボタン(マウスポインターを上に持ってくると「Insert Layout Module」と吹き出しが表れる)をクリックし、現れたモーダルウインドウでカテゴリーのスラグとブログロールのModule Typeを設定してやります。

カテゴリーとModuleのタイプを設定

Module Typeはこんな感じのものが選べます。

flexible_layouts

実際にサイトを運営し、投稿記事を書き込んだり、Google Analitycsでアクセス状況を分析してサイトのレイアウトを変えていくのに適した仕組みですよね。

サイトを作る者にとっても、テンプレートタグ&html&cssでコーディングしたり、プラグイン&cssのカスタマイズで手間ヒマかけなくていいのがありがたいです。

また管理画面の ‘外観’ > ‘Theme Options’ で、サイトに要求されるいろいろな事を設定できます。
例えば

  • ロゴ画像
  • ファビコン画像
  • Google Analytics Code
  • Default Blog Style
  • Google Fontの種類
  • PC用とスマホ用の基準フォントサイズとフォントの色
  • フッター部の自社・自己紹介とロゴ
  • FacebookやTwitter、PinterestなどSNSとの連携
  • カスタムcss

など、盛りだくさんの内容となっていますね。

GONZO、ちょっといいかもです。
GONZOにはpoファイルも有るし、また日本語化してみようかと思います。

当サイトの過去記事です → WordPressのローカライズ、つまり日本語化 – その3poとmo

WordPress管理画面のcssカスタマイズ(JavaScriptへの応用も有り)

このサイトでは、ダウンローダーにDownload Managerプラグインを使っています。
手軽に使えるし、ダウンロードファイルのパスも見えにくくしてくれるので安心だし、このサイトにはちょうどいい作りになっているんですが、一つだけ気になるところが有るんです。管理画面の ‘ダウンロード’ > ‘全てのファイル’ で表示されるダウンロードファイルの一覧のレイアウトがちぐはぐで、どうも使いにくい。

こんな感じです。

Download Managerファイル一覧 インストール直後一覧に有る ‘Short-code’ など一番使うだろう箇所なのに、内容が表示されず、コピーもしにくい状態。

そこで手っ取り早く、cssをいじってレイアウトを調整したいと思います。

1. headerにcssを書き込む方法(でも直接じゃないよ)

(cssの様な)スタイルシートは、htmlファイルのheader部分に書き込んだり、読み込ませたりするのが一般的ですが、admin-header.phpに直接書き込むわけじゃないです。
アクションフックを使い、管理画面が表示される直前に、一覧表のレイアウト修正のcssをheader部に書き込ませるんです。

具体的なやり方としては、functions.php(の ‘<?php’ 以降で ‘?>’ があればそれよりも前)に次のコードを書き込みます。

add_actionは第1引数のアクションフック ‘admin_print_styles‘ に、第2引数のコールバック関数 ‘test_admin_style_css()’ をフックします。
ざっくりと言うと、 ‘admin_print_styles‘ は管理画面のスタイルシートの登録を管理していて、そこに ‘wp_admin_style_css()’ が出力するスタイルシートを登録し、管理画面が呼び出された時、他に登録されたスタイルシートと一緒にheader内に書き出されます。
‘test_admin_style_css()’ では単純にechoを使い、直後に書かれている<style>から</style>までのcssとPHP_EOLを出力するので、個々に書かれているスタイルシートがそのまま管理画面のheader内に書き込まれるのです。
PHP_EOLは環境によって適した改行コードに切り替わるPHPの定数です。
また、’test_admin_style_css()’ 内のスタイルシートの.column-title等はタイトル等の項目名の入ったth要素のクラスで、これのwidthを操作する事で、一覧表のレイアウトを変えます。

試しにサイトからの管理画面のレスポンスのheader部分を見てみると、

となっていて、’test_admin_style_css()’ 内のスタイルシートがそのまま張り込まれているのが解ります。

管理画面を見ると、レイアウトが調整されています。

Download Managerファイル一覧 css修正後

WordPress Codex – add_action
WordPress Codex – admin_print_styles
PHP manual – echo

headerにJavaScriptを書き込む方法(応用)

管理画面のheaderにスタイルシートを書き込む為、functions.phpでadd_actionを使ってadmin_print_stylesにスタイルシートをフックさせましたが、同様の方法で、JavaScriptを書き込む事が出来ます。

この場合、アクションフックは ‘admin_print_scripts‘ を使います。
方法は、functions.phpに次の様なコードを書き込みます。

WordPress Codex – admin_print_scripts

</body>直前にJavaScriptを書き込む方法(応用)

JavaScriptでよく行われる</body>直前への書き出しもで来ます。この場合、アクションフックに ‘admin_print_footer_scripts’ を使います。

2. headerにcssファイルを呼び込む方法

ひとまずレイアウトは修正できましたが、レスポンスとはいえheaderに直接スタイルイートを書き込みのは美しくないし、実際はfunctions.phpにスタイルシートを書き込むわけだから、cssやfunctions.phpの管理の上でも宜しくない。
と言う事で、 ‘Download Manager’ のダウンロードファイル一覧ページのcssを別ファイルにし、管理画面のheaderで呼び込ませる事にします。

まず、管理画面のcssとして、 ‘admin-style.css’ を作成します。
UTF-8でエンコード出来るtext-editor(CotEdit、Me、TeraPad、Subline Text2、Atom、など)で新規作成、先程のfunctions.phpに書き込んだコードの、<style>と</style>の間のスタイルシート部分をそのままコピー&ペースト。

エンコードをUTF-8(htmlやphpと違い、BOM有無はどちらでもいい筈)、改行コードをLF(CRLFでも、いけるっちゃあいける)で、名前を ‘admin-style.css’ として保存します。

それをftpクライアントで、サイトの使用中のテーマディレクトリに直接アップロードします。
functions.phpやstyle.cssと同じディレクトリに同居する事になります。

そしてfunctions.phpから、先程打ち込んだコードをまるまる(function test_admin_style_css()からadd_action(‘admin_print_styles’, ‘test_admin_style_css’);まで)削除して元の状態に戻します。

そして、headerに ‘admin-style.css’ ファイルを呼び込むコードを書き込みます.

今回もadd_actionを使いますが、アクションフックに ‘admin_enqueue_scripts‘ を使い、管理画面のheaderに呼び込ませるスタイルシートやスクリプトに、第2引数にある ‘test_admin_css’ を加えます。
‘test_admin_css()’ では、 ‘wp_enqueue_style()‘ を使い、第1引数のハンドルネーム(この場合 ‘test_admin_css’ )で、第2引数のurl(ここでは ‘admin-style.css’ のurl)のcssファイルを追加させます。
get_stylesheet_directory_uri()‘ は使用中のテーマの有るディレクトリのurlを返すので、これに ‘/admin-style.css’ を連結する事で、 ‘admin-style.css’ のurlとなります。
get_stylesheet_directory_uri()‘ と同様の機能を持つ関数に ‘get_template_directory_uri()‘ が有ります。
子テーマを使用しいる場合、 ‘get_template_directory_uri()‘ は親テーマのディレクトリのurlを返すのに対し、’get_stylesheet_directory_uri()‘ は子テーマのディレクトリのurlを返します。
今回は子テーマでも使う事を想定し、’get_stylesheet_directory_uri()‘を使っています。

実際に管理画面のheader部分を見てみると、

となり、スタイルシートととして呼び込まれます。

管理画面を確認すると、headerに直接スタイルシートを書き込んだ場合と同じレイアウトになっていて、スタイルシートちゃんと呼び込まれているのが確認できます。
Download Managerファイル一覧 cssファイル呼び込み

WordPress Codex – admin_enqueue_scripts
WordPress Codex – wp_enqueue_style()
WordPress Codex – get_stylesheet_directory_uri()
WordPress Codex – get_template_directory_uri()

headerにJavaScriptを呼び込む方法(応用)

また、アクションフックの ‘admin_enqueue_scripts‘ はJavaScriptの呼び込みにも使えます。
JavaScriptの呼び込みには、 ‘wp_enqueue_style()‘ の代わりに ‘wp_enqueue_script()‘ を使います。
呼び込むJavascriptファイルを、使用しているテーマディレクトリにある ‘test_admin_script.js’ とすると、

となります。

</body>直前にJavaScriptを呼び込む方法(応用)

直前に読み込みたい場合もheader内に呼び込むのと同じですが、’wp_enqueue_script()‘ の第4引数を ‘true’ にします。

ひとまず ‘Download Manager’ ファイル一覧のレイアウトを調整しましたが、一覧の項目の ‘コメント’ と ‘タグ’ はあまり使わないので、削除したいと思います。
これはまた後日に。

shortcodeの前後に付くpタグの削除

WordPressサイトにちょっとした機能を持たせたりする時、functions.phpに関数を組み、投稿記事や固定ページに ‘[‘ と ‘]’ で囲まれた、その関数のshortcodeを書き込みます。
また ‘[‘ と ‘]’ で囲まれたshortcodeは、pluginなどでも、よく使ったりします。

結構簡単に使えるし、格別問題も起きないとそのままで使い続けていたりしますが、 ‘The W3C Markup Validation Service’ でサイトのhtmlがW3Cの提唱する「W3C勧告」に合致しているかチェックすると、Errorを指摘されて、びっくりする事が有ります。

The W3C – Markup Validation Service(https://validator.w3.org/)

W3C勧告でのエラー

WordPressの投稿や固定ページのエディターは、ディフォルトでは<p></p>や<br />を自動補完するんですが、エディター上で ‘[‘ と ‘]’ で囲まれたshortcodeの前後にも、勝手に<p>と</p>を付けてしまうんですね。
で、そのページを閲覧した時、shortcodeは前に<p>、後ろに</p>を付けたままhtmlに展開されてしまうので、「W3C勧告」に不適切なhtmlとなってしまうんですね。

例えば前回の投稿記事の ‘Event Organiserプラグインの完全日本語化‘ でも、downloaderにshortcodeを使っているこの箇所

download-managerの箇所

のソースを見ると、

となっています。

エディター上ではTinyMCE Advancedで<p>と<br />を表示する様に設定にしていなければ見えないので、気が付かない事がよくあります。

では対処するにはどうすれば良いか?

  1. <p></p>や<br />を自動保管させない様にする。
  2.  自動保管はさせるが、shortcodeの直前の<p>・直後</p>だけ削除する。

の2つの方法が有ります。

1. <p></p>や<br />を自動補完させない様にする。

エディターの<p></p>と<br />の補完が原因ですから、自動補完を行わない様に設定し、投稿はビジュアルエディターではなくテキストエディターを使い、必要な箇所に手動で<p></p>と<br />を打ち込む方法です。

WordPressの<p></p>と<br />の自動補完の関数は wpautop() です。
remove filter()を使って投稿の本文や抜粋を画面に出力する前に適応されるフィルターフックからwpautop() を削除してやります。

これをfunctions.phpの ‘<?php’ 以降に書き込みます(functions.php内に ‘?>’ が有る場合は、'<?php’ と’?>’ の間に書き込む)。

remove filter()は第1引数が ‘除去したい関数が追加されているフィルターフック’ 、第2引数が ‘除去したいコールバック関数’ (オプションで第3引数も有り、 ‘関数の優先順位’)を指定します。
つまり

はthe_content(投稿の本文を画面に出力する前に適応されるフィルターフック)からwpautop()(<p></p>と<br />の自動補完する関数)を除去で、

the_excerpt()関数(投稿の抜粋を画面に出力する前に適応されるフィルターフック)からwpautop()(<p></p>と<br />の自動補完する関数)を除去と言う事です。

WordPress Codex – wpautop()関数
WordPress Codex – remove filter()関数
WordPress Codex – フィルターフック(the_content・the_excerpt等)

remove filter()を使うメリット

<p></p>と<br />は自動補完されないので、気が付かない内に不必要な<p></p><br />タグが付かないので、気が付かないうちに「W3C勧告」から外れたhtmlになる様な事は無くなります。

remove filter()を使うデメリット

既に投稿された記事がたくさん有る場合、過去記事に手動で<p></p><br />タグを打ち込み直さなければいけなくなり、大変な手間となります。
ですので、基本的にWordPressサイト開始時の対策となります。

2. shortcodeの直前・直後だけ自動補完させない様にする。

この方法は、<p></p>や<br />を自動保管させるのですが、実際に投稿記事を閲覧され、投稿記事本文が呼び出された時、shortcodeの ‘<p>[‘ を'[‘に、 ‘]</p>’ を ‘]’ に、 ‘]<br />’ を ‘]’ に置き換えて表示させる方法です。

functions.phpの'<?php’ 以降に次のコードを書き込みます(functions.php内に ‘?>’ が有る場合は、'<?php’ と’?>’ の間に書き込む)。

まず呼び出された投稿本文にある ‘<p>[‘ ・ ‘]</p>’ ・ ‘]<br />’ を、strtr()関数でそれぞれ ‘[‘ ・ ‘]’ ・ ‘]’ に置き換えて返す関数 ‘shortcode_remove_p()’ を作ります。strtr()関数は連想配列のkeyを置換する前のもの・valueを置換後のものとする事で、複数の置換の組み合わせを扱えます。

そしてadd_filter()関数で、投稿本文が画面に出力される直前に、このshortcode_remove_p()関数も呼び出される様にします。

add_filter()関数は、第1引数で指定したフィルターフックに、第2引数の関数を登録します。
つまりthe_contentという投稿の本文を画面に出力する前に適応されるフィルターフックにより、本文を画面に出力する直前に、shortcode_remove_p()関数で置き換えさせるのです。

PHP – strtr()関数
WordPress Codewx – add_filter()関数

すると、

‘The W3C Markup Validation Service’ でチェックすると、Errorはなくなっています。

この方法のメリット

過去の投稿で修正する部分はshortcodeが展開された部分だけで、それも一括してcssで位置調整をすれば良いだけです。かなり簡単。

この方法のデメリット

strtr()関数でタグを置き換えているのが、少しばかり強引かもしれません。多分だ以上だとは思いますが、意外なところで動作がおかしくなるかもしれません。
正式な使用には、暫く検証した後、問題無いと確証が持ててからにしてください。