我可以将主循环更改为‘orderby’自定义回调吗?

时间:2020-08-04 作者:jamesfacts

我有一个自定义的帖子类型title 是一个名称,我想按中的最后一个单词对循环进行排序title, 姓氏。

在自定义查询中,我可以轻松地将名称分开并按最后一个单词进行过滤,但我不想重新编写归档页面的主循环/分页。是否可以将回调传递给orderby 操作中的参数pre_get_posts 还是这是一个失败的事业?

谢谢

2 个回复
最合适的回答,由SO网友:Jacob Peattie 整理而成

不,您不能传递回调函数。回调函数是PHP,因此不能在MySQL中运行。要做到这一点,需要首先从数据库中查询结果,但您会得到错误的结果,因为它们未排序。

您需要使用posts_orderby 作为SQL查询的一部分执行此操作的筛选器:

add_filter(
    \'posts_orderby\',
    function( $orderby, $query ) {
        if ( ! is_admin() && $query->is_post_type_archive( \'post_type_name\' ) ) {
            $orderby = "SUBSTRING_INDEX(post_title, \' \', -1) ASC, post_title ASC";
        }
        
        return $orderby;
    },
    10,
    2
);
使用SUBSTRING_INDEX() MySQL函数将结果按文章标题中第一个空格后的所有内容排序,然后按文章标题排序,这样,具有匹配姓氏的结果将按名字排序。

SO网友:jamesfacts

我只是为子孙后代发布了我的代码,如果有人需要下载解决方案,我对@Jacob Peatite的代码做了一些小改动:

add_filter(\'posts_orderby\', __NAMESPACE__ . \'\\surname_orderby\', 10, 2);
function surname_orderby($args, $wp_query)
{
    //make sure this is not an admin dashboard query.
    if (is_admin()) {
        return;
    }
    //check if this is the main query, rather than a secondary query such as widgets or menus.
    if (!is_main_query()) {
        return;
    }

    // the wp query at this filter is literally just the orderby value, we need to fetch the queried object
    $queriedObj = $wp_query->get_queried_object();
    
    if (isset($queriedObj->name) && $queriedObj->name === the_one_I_want ) {
        $args = "SUBSTRING_INDEX(post_title, \' \', -1) ASC, post_title ASC";
        return $args;
    }
}

相关推荐

Loop through array of pages

我正在尝试递归地获取页面的所有子级(无限深度),我正在使用下面的函数,from this solution:function get_all_subpages($page, $args = \'\', $output = OBJECT) { if (! is_numeric($page)) $page = 0; $default_args = array( \'post_type\' => \'page\',&