• 赤色のリンクは、まだ日本語Codexに存在しないページ・画像です。英語版と併せてご覧ください。(詳細

このWikiはいつでも誰でも編集できます

プラグイン API/アクションフック一覧/pre get posts

提供: WordPress Codex 日本語版
移動先: 案内検索

このフックはクエリ変数オブジェクトの生成後、実際にクエリが実行される前に呼び出されます。

pre_get_posts アクションは $query オブジェクトへの参照によるアクセス手段を開発者に提供します($query への変更はオリジナルのオブジェクトに直接反映されます - 返り値は必要ありません)。

書き方

<?php add_action( 'pre_get_posts', 'your_function_name' ); ?>

参考: 'your_function_name' は呼び出される関数の名前です。

注意

変数は参照で渡される

関数が呼び出されるとき $query オブジェクトは参照により渡されます。グローバル宣言したり値を返したりする必要はありません。関数内で行った変更はオリジナルへ直ちに反映されます。

ページリクエスト

pre_get_posts は単一の固定ページのリクエスト(ページテンプレート)に対するクエリを変更するのに用いるべきではありません。なぜなら 'is_page'、'is_singular'、'pagename' および他のプロパティ(pretty パーマリンクを使っているかどうかによる)が parse_query() メソッドによってセットされた後だからです。詳しくは クエリ概要 を見てください。

これと同様に、pre_get_posts はテンプレートファイル(例えば archive.php)内では動作しません。なぜならクエリが完了した後だからです。

これらの設定に精通していて、かつ設定を調整しようと望むのでなければ、ページテンプレート内で new WP_Query を使って単一の固定ページのリクエスト(ページテンプレート)に対するクエリを変更するのを推奨します。

本物の固定ページと静的フロントページにおける pre_get_posts の利用については以下の投稿を見ると良いでしょう。これはページネーションを pre_get_postsWP_Query クラスのフィルターで変更し、pre_get_posts が動作するように post injection を利用します。

対象となるクエリーの識別

pre_get_posts を使用するときは、変更しようとしているクエリ(が何であるか)に注意してください。便利な関数のひとつは is_main_query で、変更するクエリをメインクエリのみに制限するのに使えます。他の条件分岐タグと組み合わせて目的のページのメインクエリだけを変更しましょう。

管理画面での使われ方に注意

このフィルターは管理画面のクエリに影響を与えるのにも使えます。変更が「投稿一覧」画面に影響を与えていないか確認してください。例えば、is_main_query()is_post_type_archive( 'movie' ) をチェックするだけだと、管理画面のクエリ edit.php?post_type=movie も変更してしまいます。これを避けるには ! is_admin() もチェックしてください。

条件分岐関数に注意

pre_get_postsWP_Query がセットアップされるより前に実行されます。WP_Query に依存するいくつかのテンプレートタグや条件分岐関数は動作しません。例えば、is_front_page() は動作しませんが、is_home() は動作します。このような場合は、pre_get_posts フックに引数として渡されるクエリ変数を直接参照する必要があります(このページの用例に出てくる $query)。

オフセットとページ送り

WordPress のクエリで offset 引数を使うと(どのクエリでも)、ページ送りに不具合を引き起こすことがあります。ページ送りを保ちつつオフセットを使用するには、手動でページ送りを処理する必要があるので留意してください。詳しくは Codex の記事 Making Custom Queries using Offset and Pagination /en を見てください。


用例

メインページから特定のカテゴリーを除外

これは特定のカテゴリーに属する投稿を除外してブログに表示する方法です。例えば、ブログの「ホーム」に表示させたくない投稿のカテゴリーが2つ(未分類 '1' ともうひとつ '1347')あるなら、プラグインまたはテーマ内(functions.php)で以下のコードを使います。

function exclude_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', '-1,-1347' );
    }
}
add_action( 'pre_get_posts', 'exclude_category' );

ホームページ上に唯一のカテゴリーを表示

ホームページに唯一のカテゴリーの記事を表示するには functions.php に下記のコードを置きます。

function my_home_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', '123' );
    }
}
add_action( 'pre_get_posts', 'my_home_category' );

'123' を表示したいカテゴリーの ID に変更してください。

ホームページから ID で単一投稿を除外

ホームページから投稿 ID の配列で単一投稿を除外します。

function exclude_single_posts_home( $query ) {
  if ( $query->is_home() && $query->is_main_query() ) {
    $query->set( 'post__not_in', array( 7, 11 ) );
  }
}

add_action( 'pre_get_posts', 'exclude_single_posts_home' );

検索結果から固定ページを除外

読者がブログを検索するとき、その目的は恐らく固定ページではなく投稿の中身でしょう。ですから、検索結果から固定ページを除外することが好ましいかもしれません。投稿からの検索結果に限定するためのアクションフックを作ることができます。以下の例がその方法です。

function search_filter( $query ) {
  if ( !is_admin() && $query->is_main_query() ) {
    if ( $query->is_search ) {
      $query->set( 'post_type', 'post' );
    }
  }
}

add_action( 'pre_get_posts','search_filter' );

検索結果にカスタム投稿タイプを含める

function search_filter($query) {
  if ( !is_admin() && $query->is_main_query() ) {
    if ($query->is_search) {
      $query->set( 'post_type', array( 'post', 'movie' ) );
    }
  }
}

add_action( 'pre_get_posts','search_filter' );

投稿タイプを指定して表示件数を変更

WordPress には、ひとつのループページに表示する投稿の数を制御するためのグローバル設定がひとつあります(管理画面の 設定 > 表示設定 > 1ページに表示する最大投稿数)。この設定値を posts_per_page と呼び、ケース・バイ・ケースで変更または上書きするアクションフックを作成できます。何が良いかって、これはクエリを実行するより前に実行されるので、パフォーマンスに影響を与えないのです!

以下の例は特定の投稿タイプのアーカイブに対して、1ページに表示する投稿数 ('posts_per_page') を上書きする手法を示します。

function hwl_home_pagesize( $query ) {
    if ( is_admin() || ! $query->is_main_query() )
        return;

    if ( is_home() ) {
        // オリジナルのブログアーカイブは投稿を1つ表示
        $query->set( 'posts_per_page', 1 );
        return;
    }

    if ( is_post_type_archive( 'movie' ) ) {
        // Display 50 posts for a custom post type called 'movie'
        // カスタム投稿タイプ 'movie' は50の投稿を表示
        $query->set( 'posts_per_page', 50 );
        return;
    }
}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );

フィードに出力する投稿数を変更

posts_per_rss の設定を使用して特定のフィードに表示する投稿数を上書きできます。

function bdn_feed_set_posts_per_rss( $query ) {

	if( !$query->is_main_query() || !is_feed() )
		return;
	
	//条件に応じた設定

	$query->set( 'posts_per_rss', 50 );

}

WP_Query オブジェクトの例

参考として、このフックで出力してみた WP_Query オブジェクト ($query) の一例を示します。詳しくは、WP_Query の codex ページを参照してください。

WP_Query Object
(
    [query_vars] => Array
        (
            [page] => 
            [pagename] => blog
            [error] => 
            [m] => 0
            [p] => 0
            [post_parent] => 
            [post_type] =>
            [subpost] => 
            [subpost_id] => 
            [attachment] => 
            [attachment_id] => 0
            [name] => 
            [static] => 
            [page_id] => 0
            [second] => 
            [minute] => 
            [hour] => 
            [day] => 0
            [monthnum] => 0
            [year] => 0
            [w] => 0
            [category_name] => 
            [tag] => 
            [cat] => 
            [tag_id] => 
            [author_name] => 
            [feed] => 
            [tb] => 
            [paged] => 0
            [comments_popup] => 
            [meta_key] => 
            [meta_value] => 
            [preview] => 
            [s] => 
            [sentence] => 
            [fields] => 
            [category__in] => Array
                (
                )

            [category__not_in] => Array
                (
                )

            [category__and] => Array
                (
                )

            [post__in] => Array
                (
                )

            [post__not_in] => Array
                (
                )

            [tag__in] => Array
                (
                )

            [tag__not_in] => Array
                (
                )

            [tag__and] => Array
                (
                )

            [tag_slug__in] => Array
                (
                )

            [tag_slug__and] => Array
                (
                )

        )

    [tax_query] => 
    [meta_query] => 
    [post_count] => 0
    [current_post] => -1
    [in_the_loop] => 
    [comment_count] => 0
    [current_comment] => -1
    [found_posts] => 0
    [max_num_pages] => 0
    [max_num_comment_pages] => 0
    [is_single] => 
    [is_preview] => 
    [is_page] => 
    [is_archive] => 
    [is_date] => 
    [is_year] => 
    [is_month] => 
    [is_day] => 
    [is_time] => 
    [is_author] => 
    [is_category] => 
    [is_tag] => 
    [is_tax] => 
    [is_search] => 
    [is_feed] => 
    [is_comment_feed] => 
    [is_trackback] => 
    [is_home] => 1
    [is_404] => 
    [is_comments_popup] => 
    [is_paged] => 
    [is_admin] => 
    [is_attachment] => 
    [is_singular] => 
    [is_robots] => 
    [is_posts_page] => 1
    [is_post_type_archive] => 
    [query_vars_hash] => 41032f87127fba65fb6743b1e97d8662
    [query_vars_changed] => 
    [thumbnails_cached] => 
    [query] => Array
        (
            [page] => 
            [pagename] => blog
        )

    [queried_object] => stdClass Object
        (
            [ID] => 16
            [post_author] => 1
            [post_date] => 2012-01-31 17:23:57
            [post_date_gmt] => 2012-01-31 17:23:57
            [post_content] => 
            [post_title] => Blog
            [post_excerpt] => 
            [post_status] => publish
            [comment_status] => open
            [ping_status] => open
            [post_password] => 
            [post_name] => blog
            [to_ping] => 
            [pinged] => 
            [post_modified] => 2012-01-31 17:23:57
            [post_modified_gmt] => 2012-01-31 17:23:57
            [post_content_filtered] => 
            [post_parent] => 0
            [guid] => 

記事

コード・ドキュメンテーション

  • クラス: WP_Query - WP_Query クラスの詳細な全容
  • クラス: WP_Comment_Query - コメント関連のクエリのためのクラス
  • クラス: WP_User_Query - ユーザー関連のクエリのためのクラス
  • オブジェクト: $wpdb - $wpdb オブジェクトの使い方全容
  • 関数: set_query_var()
  • 関数: get_query_var()
  • 関数: query_posts() - 追加のカスタムクエリを作成
  • 関数: get_post() - 項目の ID を取得しデータベース内にあるその投稿のレコードを返す
  • 関数: get_posts() - 投稿の配列を返すことに特化した関数
  • 関数: get_pages() - ページの配列を返すことに特化した関数
  • 関数: have posts() - クエリが投稿を返すか否かを判断する条件関数
  • 関数: the_post() - クエリ後に自動的にループを設定する
  • 関数: rewind_posts() - 現状のループをリセットする
  • 関数: setup_postdata() - ループ内で個別の結果を得るためのクエリデータを設定する
  • 関数: wp_reset_postdata() - 直前のクエリを復元する (通常はループ内の別のループの後に用いられる)
  • 関数: wp_reset_query()
  • 関数: is_main_query() - 変更されるクエリがメインのクエリであることを確認する
  • アクションフック: pre_get_posts - WordPressクエリが実行される前に変更する
  • アクションフック: the_post - post クエリの後で post オブジェクトを変更する
  • フィルターフック: found_posts - WP_Query オブジェクトの found_posts 値を変更する


関数リファレンステンプレートタグ目次もご覧ください。


最新英語版: WordPress Codex » Plugin_API/Action_Reference/pre_get_posts最新版との差分