WordPressサイトのトップページでカスタムポストタイプの投稿のみを表示させる方法をメモ。
is_main_query関数とpre_get_postsフックを使って、loopの記述を改変しなくてもhome.phpの出力内容を通常の投稿からカスタム投稿に変えることができるという手法です。
functions.phpに以下のコードを記述します。
<?php
add_action( 'pre_get_posts', 'foo_modify_query_exclude_category' ); // pre_get_postsにフック
// フック時に使う関数
function foo_modify_query_exclude_category( $query ) {
if (! is_admin() && $query->is_main_query() && $query->is_home()) // 管理画面以外 かつ メインクエリ かつ home
$query->set( 'post_type', 'custom-post'); // カスタムポストタイプ custom-post をセット
}
?>
home.phpが使われる時、つまりトップページが表示されるときにcustom-postという名前のカスタム
投稿が表示されるようになります。(カスタムポストタイプは予め作っておく。)
home.phpでは例えば以下のような通常のメインクエリを出力するloop処理を呼び出しています。
//以下はget_template_part()によって呼び出されたloop.phpの中身
<?php if (have_posts()) : ?>
// 投稿一覧を表示する前の処理内容
<?php while (have_posts()) : the_post(); ?>
// 各投稿を表示する処理内容
<?php endwhile; ?>
// 投稿一覧を表示した後の処理内容
<?php else : ?>
// 投稿が無いときの処理内容
<?php endif; ?>
以下の様なメリットがあります。
is_main_query 関数と pre_get_posts フックを使う事で、テンプレートファイルにアクセスする前にメインクエリを改変することが可能です。つまり、二重にクエリの呼び出しを行わなくて済むというメリットがあります。
また、query_posts を使う方法だと、変更したいテンプレートファイルすべてに条件変更の記述をしなければなりませんが、is_main_query と pre_get_posts フックを使う方法は functions.php 一箇所に書けば大丈夫というメリットがあります。
引用元:WordPressでホームやアーカイブ毎に表示条件を変える(is_main_query と pre_get_posts フック) | Gatespace’s Blog
通常のループ処理だと”メインクエリ”を呼び出す、つまり通常の投稿内容を表示させることになるのですが、上記処理にてメインクエリを投稿からカスタム投稿に変更しているということのようです(home.phpが使われる場合に限って)。
ざっくばらんなまとめ(推測含む)。
add_action( 'pre_get_posts', 'foo_modify_query_exclude_category' );
→pre_get_postsにフックする関数foo_modify_query_exclude_categoryを指定。
if (! is_admin() && $query->is_main_query() && $query->is_home())
→関数foo_modify_query_exclude_categoryの条件を定義。条件は管理画面以外でメインクエリを呼び出しているとき、且つテンプレートがhome.phpである場合。
$query->set( 'post_type', 'custom-post');
→関数foo_modify_query_exclude_categoryの条件が満たされたら、$queryにcustom-postという投稿タイプをセットする。
以上の文脈から推測すると$queryがメインクエリのような気がします。
もっともっとまとめると、関数foo_modify_query_exclude_categoryが実行されてメインクエリが改変され、home.php(呼び出されたループ処理)によってhome.phpでカスタム投稿タイプが出力されるという流れ…なんだと思います。多分。
参考サイト:
WordPressをカスタマイズするなら覚えておきたいアクションフックとフィルターフック