ウィジェット自体の出力条件を含め、ウィジェットエリアがウィジェットを出力するか判別する方法
ウィジェットエリアが出力するアイテムがあるかどうかって、どうチェックしていますか?
通常は恐らく「is_active_sidebar」を使用すると思うんですが、条件付きでコンテンツを出力するウィジェットを使ってみると、この関数が役に立たないことが分かると思います。
そこで自分なりに改良して、便利な方法を見つけましたので紹介しておきます。
何故「is_active_sidebar」では不十分なのか
不十分というのは、あくまで僕にとって、もしくは僕が作成しているテーマにとってという意味です。
例えば、テーマ「ShapeShifter」では、ウィジェットの出力条件によって出力されなかったウィジェットがある場合、ウィジェットエリアが「非アクティブ」なものとして扱い、コンテンツエリアの横幅やカラム数を変化させたいと思っていました。
ただ、ワードプレス関数「is_active_sidebar」はウィジェットエリアにウィジェットが配置されているかどうかを確認し、配置されていれば「true」配置されていなければ「false」を返す関数です。
if( is_active_sidebar( 'widget-area-id' ) ) { // ID「widget-area-id」のウィジェットエリアにウィジェットが配置されている場合の処理 }
こんな感じで使用され、だいたい「dynamic_sidebar」で配置されているウィジェットを出力します。
ところが、ウィジェット自体に設定として出力条件を指定し、出力したくない条件に合致して「return」してしまうウィジェットが配置されている場合でも、この「is_active_sidebar」はウィジェットが配置されている為に「true」を返してしまい、結果、その時に何も出力されていない状態だったとしても、ウィジェットエリア用に用意されるHTMLが横幅を取るなどしてレイアウトが柔軟にならないんです。
レイアウトはCSSでどうにか出来ればいいのかもしれませんが、何もない空の不要なHTMLタグを出力したくはないので、これを回避する方法が必要だと思ったんです。
一度Stringとして取得すればチェックできる
ウィジェットエリアの出力する値をStringで取得する関数は用意されていませんので、バッファリングを使用して値を取得します。
if( ! is_active_sidebar( 'your_widget_area' ) ) return false; ob_start(); if( function_exists( 'dynamic_sidebar' ) && dynamic_sidebar( 'your_widget_area' ) ) {} $your_widget_area = ob_get_clean(); if ( ! empty( $your_widget_area ) ) { echo '<div class="widget-area"><ul class="widget-list">'; echo $your_widget_area; echo '</ul></div></div>'; }
値を返すこともできますので、それを利用してウィジェットエリアのその更に外側のコンテナーの出力なども変化させることができます。
ウィジェットに出力条件を設定しているのであれば、知っておいて損しないと思います。
注意点
この方法が使用できるのは、テンプレートファイル「single.php」などが読まれる時で、「functions.php」から直接読まれる時点では恐らく正確に判別することができません。
というのは、ページによる出力条件を指定している場合、その多くが「アーカイブページの場合」や「投稿ページの場合」などだと思いますが、「is_archive」や「is_single」などは「functions.php」で呼び出しても正確な判別はしてくれない関数です。また、ウィジェットはプラグインが用意しているものもあるでしょうから、どのような条件を付けているかなんてコードを読まないと判別できません。
つまり、ちゃんと条件分岐用の関数が正常に働く時点、テンプレートファイルが読まれた後でこの判別は行うようにする必要があります。ちょっと面倒ですけどね。
ですので、テーマ「ShapeShifter」でも、コンテンツエリアの設定は基本的に「index.php」で行うようにしています。