WordpressのウィジェットエリアでPHPを使うために、 「PHP Code Widget」や「Enhanced Text Widget」などのプラグインをお使いの方も多いと思います。
どちらも詳しい説明が要らないほどシンプルなプラグインですが、get_posts関数でサブクエリーを作ろうとすると、どうもうまくいきません。こちらのケースで半日ほど時間を潰してしまったので、解決方法をシェアしたいと思います。(原因を知ってしまえば「なーんだ」くらいのことです)
ウィジェットエリアでget_postsが正常動作しない
では早速、下記のコードをご覧ください。
- <?php
- $args = array(
- 'posts_per_page' => '3',
- 'category' => '2',
- ); ?>
- <?php
- $posts = get_posts( $args );
- ?>
- <?php foreach ( $posts as $post ): setup_postdata ( $post ); ?>
- <h3><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h3>
- <?php endforeach; wp_reset_postdata(); ?>
ざっくりと内容を説明すると、get_postsでカテゴリーIDが「2」の記事を3つ抽出し、リンク付きタイトルを出力するという基本的なコードです。
さて、上記のコードですが、index.phpなどのテンプレート上に直接書いた場合、何の問題も無く動作します。
しかし、「PHP Code Widget」等のプラグインを使い、ウィジェットエリアに記述しても、正常に動作してくれません。
$postsをグローバル変数として宣言する
では、単刀直入に解決方法を書きますと、コード中の$post変数を、グローバル変数として宣言します。
具体的には上で書いたコードの前に、下記コードを記述します。
- <?php
- global $post;
- ?>
これでget_postsが正常に動作します。
若干補足しますと、$postはループ内で使われる既定の変数です。試しに$postを別の変数名に変更したところ、やはりループ(foreach)がうまく動作しませんでした。
なお、get_postsやforeach関数の使い方などを体系的に理解したい方には、下記書籍のP203以降を読まれることをお勧めします。コピペだけでそれなりにカスタマイズできるWordpressですが、仕組みを知っていると自力で対処できるケースも増えます。
ちなみに、今回のケースですが、意外にもレアなのか、事例や解決方法がネットでほとんど見当たりません。
もしかして自分の環境に原因があるのかも?と疑い、本記事をリリースする前に海外サイトも確認したところ、いちおう既出のトラブルではあるようです。
というわけで以上です。もし何かあればコメント欄にてフィードバックしていただければと思います。