kinalog

自称フロントエンドエンジニアが何か喚いています。

投稿ページをアーカイブページっぽくしたかった

投稿ページをアーカイブページっぽくしたかった。ただそれだけのために1日悩んだので、悩んだ成果をここに残します。
query_posts使えば一撃なんだけど、それってナウでヤングじゃないので、がんばってpre_get_postsでやりたかった、ただそれだけなんです。

結論から言うと

素直にget_postsかWP_Queryを使っとけってお話だった。

何がしたかったのか

通常の投稿(post)の個別ページのメインクエリを変更して、カテゴリページのように同じカテゴリの記事の一覧を表示させたかった。

query_postsとは何か

WordPressのメインクエリを書き換えるための、テンプレートタグ。一昔前は皆使ってたけど、非効率的ってことで段々数を減らしている(のか?)

pre_get_postsとは何か

WordPressがクエリーを取得するまえに必ず実行されるフィルターフック

query_postsを捨てよ、pre_get_postsを使おう【追記あり】【報告あり】 | notnil creation weblog

こいつをいじることにより、テンプレートを汚さずメインクエリが書き換えられる。

具体的な使い方

functions.php内で

function my_main_query( $query ) {
    if( is_admin() || ! $query->is_main_query() ) {
        return;
    }
    
    // ここに条件を書く
    if( $query->is_home() ) {
        $query->set( 'posts_per_page', 10 );
        ・
        ・
        ・
    }
}

add_action( 'pre_get_posts', 'my_main_query' );

っていう感じで書くと、ループの部分は特に何も書き換えずに、簡単に表示される記事を変更できる。

試行錯誤したが・・・

is_home()での分岐は普通にできて、ページ送りも気にしなくてOKでらくちーんと思ってたんだけど、表題のことをやろうとして撃沈。


まず、is_singular('post')で条件分岐を考えてたんだけど、

Notice : Trying to get property of non-object in /(WPインストールディレクトリ)/wp-includes/query.php on line 4483

とか言われちゃって、なんだかうまくうごかない。

is_singular()単体だと何も出ずにいけるんだけど、引数設定するとだめなようなので諦めた。(カスタム投稿タイプとかには反映させたくなかったから)

その後しばらく頭を捻って、こんな風に設定してみた。

if( get_post_type( $query->get( 'p' ) ) === 'post' ) {
・・・
}

これはうまくいって、特にエラーも出なかった。
これで中身に

$query->set( 'post_type', array( 'post' ) );
$query->set( 'posts_per_page',  -1 );

って書いたらうまくいくかな、と思ってたんだけど、現実は厳しく、現在見ているページの記事しか表示されてない。

多分クエリで記事IDでも指定されてるんじゃろ、と思ったので

$query->set( 'p',  '' );

とか設定してみたら、今度は記事が1件もないっていう状態に。
その後もunsetとかでqueryの中身をいじってみたりしたけど、全然ダメ。完全にお手上げ状態に。

その後

Google先生に必死に助けを乞うた結果、下記のような記事を見つけた。
http://www.wp-mynote.com/2013/04/pregetpostspost.html

こちらの方の結論としては「やらないほうが良い」


このスライドだと、「固定ページをアーカイブに等根本的に変更するのは厳しい」
多分これは通常の投稿でも同じなんだろうね・・・。



というわけで、ナウでヤングな書き方もいいけど、出来ないことを先に把握しとけよっていう反省の話でした。