WordPressのややこしい挙動シリーズ、第何弾目かわかりませんが、ちょくちょく出てくるので忘れないように書いておこうと思います。
get_posts()というWordPress関数があります。
投稿一覧(またはページ一覧)を取得するものなので、テーマを作る時などには結構使うと思います。
しかしget_posts()には、知らないと混乱する仕様があります。
たとえば、公式リファレンスにならって次のようなコードを書いたとします。
‘date’,
‘order’ => ‘DESC’,
‘include’ => implode(“,”,get_option(‘sticky_posts’)),
‘post_status’ => ‘publish’
);
$posts_array = get_posts( $args ); ?>
これは「先頭に固定」とした投稿のみを抽出することを意図したものです。
では、この条件で「先頭に固定」投稿が1つも無い場合、$posts_array
の内容はどうなるでしょうか?
結果は「最新の投稿が5件表示される」です。
どうしてこういうことになるのかというと、多少ややこしい条件があるわけです。
ソースコードを見てみましょう。
https://core.trac.wordpress.org/browser/trunk/src/wp-includes/post.php#L1661
これを見るとまず、
include
が指定されている場合posts_per_page
はget_option('sticky_posts')
の件数となります。
次に、get_option('sticky_posts')
の件数は 0 なので、posts_per_page
には 0 がセットされます。
と同時に、post__in
には空の配列がセットされるので、検索条件は指定無しになります。
しかしこの際、numberposts
が指定されていないので、numberposts
には初期値の 5 がセットされています。
numberposts
が空または 0 でない場合には、posts_per_page
はnumberposts
で上書きされます。
この後、WP_Query::query()
にパラメータとして渡されるわけですが、その時点でposts_per_page
が空または 0 の場合には、posts_per_page
はget_option( 'posts_per_page' )
で上書きされます。
get_option( 'posts_per_page' )
は、管理画面での設定値を使うということですので、逆に言えば、管理画面での設定値を使用したいのであれば、あらかじめget_option('sticky_posts')
値を取得しチェックの上posts_per_page
として指定するか、numberposts
を 0 として明示的に指定しなければならない、ということになります。
https://core.trac.wordpress.org/browser/trunk/src/wp-includes/class-wp-query.php#L1759