当前浏览:首页 / WordPress钩子 / pre_get_posts

do_action_ref_array( 'pre_get_posts', WP_Query $query )

在创建查询变量对象后,但在运行实际查询之前触发

postsmore...

premore...


描述

注意:如果使用条件标签,请在传递的实例中使用方法版本(例如,$this->is_main_query()而不是is_main_query())。这是因为像is_main_query()这样的函数是针对全局$wp_query实例而不是传递的实例进行检测的。


参数

$query

(WP_Query) WP_Query实例(通过引用传递)。


更多信息

针对正确的查询

使用pre_get_posts动作时,请注意您正在更改查询。利用条件标签以确定正确的查询。例如,建议在管理界面中使用is_admin()条件判断,而不是直接更改查询。通过查询对象中的$query->is_main_query()条件,您可以将页面请求的主查询作为目标,主查询由主文章循环使用,该循环显示文章、页面或存档的主要内容。如果没有这些条件,您可能会无意中更改边栏、页脚或其他位置中自定义循环的查询。

以类别存档的主查询为目标的示例:

function target_main_category_query_with_conditional_tags( $query ) {
	if ( ! is_admin() && $query->is_main_query() ) {
		// Not a query for an admin page.
		// It's the main query for a front end page of your site.

		if ( is_category() ) {
			// It's the main query for a category archive.

			// Let's change the query for category archives.
			$query->set( 'posts_per_page', 15 );
		}
	}
}
add_action( 'pre_get_posts', 'target_main_category_query_with_conditional_tags' );

默认主查询参数

主查询(对象)已经根据页面请求设置了一些默认属性。例如,对于单个文章,$query->is_single属性设置为true。这意味着您不能简单地将单个文章或页面查询更改为文章存档查询(或相反)。要实现这一点,必须在查询对象本身中重置这些属性。除非您非常熟悉这些设置并愿意自己协调它们,否则建议您在page.php或single.php(子)主题模板文件中使用WP_Query替换主查询。

关于条件函数的警告

pre_get_postsWP_Query设置之前运行。一些模板标签和依赖WP_Query的条件函数将无法工作。例如,is_front_page()起作用,尽管is_home()将起作用。在这种情况下,您需要直接使用查询变量,这些变量作为参数传递给pre_get_posts钩子(本页示例中为$query)。

偏移和分页

在任何WordPress查询中使用offset参数都会中断分页。如果需要使用offset并保留分页,请记住需要手动处理分页。有关详细信息,请阅读codex文章使用偏移和分页进行自定义查询。

基本示例

从主页中按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 date_search_filter($query) {
	if ( ! is_admin() && $query->is_main_query() ) {
		if ( $query->is_search ) {
			$query->set( 'date_query', array(
				array(
					'after' => 'May 17, 2019', 
				)
			) ); 
		}
	}
}
add_action( 'pre_get_posts', 'date_search_filter' ); 

按文章类型更改每页的文章数量

function hwl_home_pagesize( $query ) {
	if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'movie' ) ) {
		// Display 50 posts for a custom post type called 'movie'
		$query->set( 'posts_per_page', 50 );
		return;
	}
}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );


源码

查看源码 官方文档


更新日志

版本描述
2.0.0开始引入

使用示例

  • 示例1
    /**
     *
     *	The Code below will modify the main WordPress loop, before the queries fired,
     *	to only show posts in the halloween category on the home page.
     *
     */
    	function wpdocs_exclude_category( $query ) {
    		if ( $query->is_home() && $query->is_main_query() && ! is_admin() ) {
    			$query->set( 'category_name', 'halloween' );
    		}
    	}
    	add_action( 'pre_get_posts', 'wpdocs_exclude_category' );
    
  • 示例2

    有关如何调整“event”文章类型的查询的示例:

    function university_adjust_queries($query){
       if ( ! is_admin() && is_post_type_archive( 'event' ) && $query->is_main_query() ) {
            $query->set( 'meta_key', 'event_date' );
            $query->set( 'orderby', 'meta_value_num' );
            $query->set( 'order', 'ASC');
            $query->set( 'meta_query', array(
                array(
                    'key'     => 'event_date',
                    'compare' => '>=',
                    'value'   => date('Ymd'),
                    'type'    => 'numeric',
                )
            ) );
       }
    }
    add_action( 'pre_get_posts', 'university_adjust_queries' );
    
  • 示例3

    在主页中包含自定义文章类型

    function add_custom_pt( $query ) {
      if ( !is_admin() && $query->is_main_query() ) {
        $query->set( 'post_type', array( 'post', 'the_custom_pt' ) );
      }
    }
    add_action( 'pre_get_posts', 'add_custom_pt' );
    

    包括在搜索结果中

    function add_custom_pt( $query ) {
      if ( !is_admin() && $query->is_main_query() ) {
        if ( $query->is_search ) {
          $query->set( 'post_type', array( 'post', 'the_custom_pt' ) );
        }
      }
    }
    add_action( 'pre_get_posts', 'add_custom_pt' );
    

    用自定义文章类型的名称替换‘the_custom_pt’。

  • 示例4

    您可以从“最近的文章”或其他不包含meta键的小工具中筛选文章或页面。在本例中,‘transk_lang’是分配给文章和页面的meta key。

    add_action( 'pre_get_posts', 'wpdocs_pre_get_posts' );
    
    function wpdocs_pre_get_posts( $query ) {   
        // avoid main query
        if ( $query->is_main_query() ) {
            return;
        }
    
        // avoid filtering menu items
        if ( 'nav_menu_item' === $query->query_vars['post_type'] ) {
            return;
        }
        
        // add meta query
        $meta_query = $query->get( 'meta_query' );
        if ( ! is_array( $meta_query ) ) {
            $meta_query = array();
        }
           
        $meta_query[] = array(
            'key'     => 'transk_lang',
            'value'   => get_user_locale(),
            'compare' => '==',
        );
    
        $query->set( 'meta_query', $meta_query );
    }