WordPress pre_get_posts不起作用 [英] WordPress pre_get_posts not working

查看:71
本文介绍了WordPress pre_get_posts不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一些背景:

  • 我正在尝试替换存档模板的默认主查询,并返回自定义帖子类型(天")的子集,其中相对于键日期"的元值在某个值之间
  • 天"的自定义帖子类型具有日期"的自定义变量字段,用于将与该帖子相关联的每个日期的各个数据库行存储在标准wp_postmeta表中,并以纪元格式(U)存储
  • 我非常有信心SQL查询能够正常运行.在每种情况下,返回的帖子ID在查询的日期范围内都是正确的.
  • I'm trying to replace the default main query for archive templates, and to return a subset of a custom post type ('days') where meta values against the key 'dates' is between a certain value
  • The 'days' custom post type has a custom variable field of 'dates' which stores individual database rows in the standard wp_postmeta table for each date associated with that post, stored in Epoch format ('U')
  • I'm fairly confident that the SQL query is functioning correctly; the post IDs it returns appear to be correct in each case for the date range queried.

我正在函数文件中运行以下查询:

I'm running the following query in my functions file:

   function modify_queries( $query ) { 
        global $wpdb;
        if ( $query->is_post_type_archive('days') && $query->is_main_query() ) {
            // Get Days with a date within the archive range
            $year = substr($query->query_vars['m'],0,4);
            $month = substr($query->query_vars['m'],4,2);
            $day = substr($query->query_vars['m'],6,2);

            if (is_year()) {
                $startDate = date('U', mktime(0, 0, 0, 1, 1, $year));
                $endDate = date('U', mktime(0, 0, 0, 12, 31, $year));
            }
            if (is_month()) {
                $startDate = date('U', mktime(0, 0, 0, $month, 1, $year));
                $endDate = date('U', mktime(0, 0, 0, $month, cal_days_in_month(CAL_GREGORIAN, $month, $year), $year));
            }
            if (is_day()) {
                $startDate = date('U', mktime(0, 0, 0, $month, $day, $year));
                $endDate = date('U', mktime(0, 0, 0, $month, $day, $year));
            }

            $request  = "SELECT ID FROM $wpdb->posts, $wpdb->postmeta";
            $request .= " WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id";
            $request .= " AND post_status='publish' AND post_type='days'";
            $request .= " AND $wpdb->postmeta.meta_key = 'dates' AND $wpdb->postmeta.meta_value >= $startDate AND $wpdb->postmeta.meta_value <= $endDate LIMIT 0 , 30";
            $postsList = $wpdb->get_results($request,ARRAY_N);
            if ($postsList) {


                foreach ($postsList as $thePost) {
                    $thePostList[] = $thePost[0];
                }
                $query->set( 'post__in', $thePostList);
                $query->set( 'post_type', 'days');

                return;
            } else {
                return false;
            }

}
add_action( 'pre_get_posts', 'modify_queries',1 );

我的理解是,这应该获取查询的输出,并使用从SQL查询返回的ID替换为普通查询,但是,它只是返回5个最近的"days"帖子.

My understanding is that this should take the output of the query and simply replace the normal query with one using the IDs returned from the SQL query - however, it's just returning the 5 most recent 'days' posts.

目前,archive.php文件仅包含以下内容,因此我们可以排除任何干扰:

At present, the archive.php file consists purely of the following, so we can rule out any interference:

<?
while ( have_posts() ) : the_post();
global $post;
the_title();
endwhile;
?>  

我收到了5条最近发布的天"帖子,似乎忽略了pre_get_posts过滤器应该已经通过的ID.

I get the 5 most recently published 'days' posts, and it seems to ignore the IDs that the pre_get_posts filter should have passed it.

我暗中怀疑该问题的一部分与在主查询上设置"post_id"有关,而不是与"p"有关,但是我似乎根本没有得到任何结果.

I have a sneaky suspicion that part of the problem relates to setting 'post_id' on the main query, rather than 'p', but I don't seem to get any results at all with the latter.

我已经四处搜寻,但是除了作为替代query_posts的有用和有益之处之外,找不到关于pre_get_posts的大量文档.

I've hunted around, but can't find much documentation about pre_get_posts other than how useful and beneficial it is as a replacement to query_posts.

实时调试输出: http://dev.daysoftheyear.com/days/2012/10

推荐答案

您可以在 http://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts上的pre_get_post过滤器上找到文档. rel ="nofollow"> http://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts

You can find the documentation on the pre_get_post filter here http://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts

在我看来,问题实际上是您如何设置要检索的post_id.如果您参考上面的链接,则可以看到可以在传递给过滤器的$query对象上设置的不同值,而post_id不是其中之一,这就是为什么它在以下情况下起作用"的原因设置它,而设置p则不起作用".后者用于单个帖子ID,因此如果您只想使用100,则可以使用$query->set('p', 100).如果要返回帖子ID在数组中的结果,请使用$query->set('post__in', array(100, 120)).您的SQL代码只是返回ID,因此您可以直接获取一个数组,而不必返回对象,而是直接获取一个数组-我假设回显标题和print_r行只是调试:

It looks to me like the problem is in fact how you are setting the post_ids that you want to retrive. If you refer to the link above, you can see the different values that can be set on the $query object that is passed to the filter, and post_id isn't one of them, which is why it "works" when you set it, and "doesn't work" when you set p. The latter is for a single post ID, so if you just wanted 100, you would use $query->set('p', 100). If you want to return results where the post ID is in an array, you use $query->set('post__in', array(100, 120)). Your SQL code is just returning the ID, so rather than returning objects, you can just get an array directly - I'm assuming that echoing the title and print_r lines are just debugging:

// get results as a numeric array
$post_ids = $wpdb->get_results($request, ARRAY_N);
// pass post id array to $query
$query->set( 'post__in', $post_ids );

如果在$query上设置了现有的冲突参数,您也可能无法获得结果.您可以使用var_dump($query->query_vars)检查这些值,并将任何可能冲突的值设置为空字符串-在您的情况下$query->set( 'm', '' );

You may also not get results if there are existing conflicting parameters set on the $query. You can check these values with var_dump($query->query_vars) and set any that may be in conflict to an empty string - in your case $query->set( 'm', '' );

这篇关于WordPress pre_get_posts不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆