ねかつちう。

お金や節約に敏感な20代30代のための物欲系雑記ブログ

【Wordpress】PHP Code Widgetプラグインでget_postsが動かない場合の解決策

[PR]このページにはアフィリエイトプログラムによる商品・サービス等の広告を掲載しています

WordpressのウィジェットエリアでPHPを使うために、 「PHP Code Widget」や「Enhanced Text Widget」などのプラグインをお使いの方も多いと思います。

どちらも詳しい説明が要らないほどシンプルなプラグインですが、get_posts関数でサブクエリーを作ろうとすると、どうもうまくいきません。こちらのケースで半日ほど時間を潰してしまったので、解決方法をシェアしたいと思います。(原因を知ってしまえば「なーんだ」くらいのことです)

ウィジェットエリアでget_postsが正常動作しない

では早速、下記のコードをご覧ください。

  1. <?php
  2.  $args = array(
  3.  'posts_per_page' => '3',
  4.  'category' => '2',
  5.  ); ?>
  6. <?php
  7.  $posts = get_posts( $args );
  8.  ?>
  9. <?php foreach ( $posts as $post ): setup_postdata ( $post ); ?>
  10. <h3><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h3>
  11. <?php endforeach; wp_reset_postdata(); ?>

ざっくりと内容を説明すると、get_postsでカテゴリーIDが「2」の記事を3つ抽出し、リンク付きタイトルを出力するという基本的なコードです。

さて、上記のコードですが、index.phpなどのテンプレート上に直接書いた場合、何の問題も無く動作します。

しかし、「PHP Code Widget」等のプラグインを使い、ウィジェットエリアに記述しても、正常に動作してくれません。

$postsをグローバル変数として宣言する

では、単刀直入に解決方法を書きますと、コード中の$post変数を、グローバル変数として宣言します。

具体的には上で書いたコードの前に、下記コードを記述します。

  1. <?php
  2. global $post;
  3. ?>

これでget_postsが正常に動作します。

若干補足しますと、$postはループ内で使われる既定の変数です。試しに$postを別の変数名に変更したところ、やはりループ(foreach)がうまく動作しませんでした。

なお、get_postsやforeach関数の使い方などを体系的に理解したい方には、下記書籍のP203以降を読まれることをお勧めします。コピペだけでそれなりにカスタマイズできるWordpressですが、仕組みを知っていると自力で対処できるケースも増えます。

ちなみに、今回のケースですが、意外にもレアなのか、事例や解決方法がネットでほとんど見当たりません。

もしかして自分の環境に原因があるのかも?と疑い、本記事をリリースする前に海外サイトも確認したところ、いちおう既出のトラブルではあるようです。 

wordpress.stackexchange.com

というわけで以上です。もし何かあればコメント欄にてフィードバックしていただければと思います。