按自定义域对帖子排序,如果自定义域为空,则返回剩余的帖子

时间:2012-06-14 作者:Ryan

我有一个按自定义字段中的数值排序的存档页。这将正确返回已排序的帖子,但不会显示没有自定义字段的帖子。

$paged = (get_query_var(\'paged\')) ? get_query_var(\'paged\') : 1; 
query_posts("paged=$paged&cat=7&posts_per_page=24&meta_key=custom_order&orderby=meta_value_num&order=ASC");
要正确返回已排序的帖子,然后返回没有自定义字段值的帖子,最好的方法是什么?

Edit: 我想做的最后一个结果是创建一个类别归档页面,该页面首先显示特定的帖子,然后显示其他帖子。与粘性帖子非常相似,但仅适用于特定类别的归档。

Edit Two: 我正在尝试杰西卡的建议,我想我们就快到了。

问题是如果我现在开始order=ASC 然后,所有填充了自定义字段的帖子都会显示在没有关联值的帖子之后。如果我设置order=DESC 然后,首先返回具有自定义字段值的帖子,但返回的顺序相反。因此,它将显示4、3、2、1,然后是其他没有关联值的帖子。如何更正顺序,使其显示1、2、3、4,然后显示中没有值的其余帖子custom_order 领域

我在我的函数中添加了以下内容。php:

function wpse_55791_custom_order($clauses)
{
    global $wp_query;

    // check for order by custom_order
    if ($wp_query->get(\'meta_key\') == \'custom_order\' && $wp_query->get(\'orderby\') == \'meta_value_num\')
    {
        // change the inner join to a left outer join, 
        // and change the where so it is applied to the join, not the results of the query
        $clauses[\'join\'] = str_replace(\'INNER JOIN\', \'LEFT OUTER JOIN\', $clauses[\'join\']).$clauses[\'where\'];
        $clauses[\'where\'] = \'\';
    }
    return $clauses;
}
add_filter(\'get_meta_sql\', \'wpse_55791_custom_order\', 10, 1);
function wpse_55791_custom_orderby($orderby)
{
    global $wp_query;

    // check for order by custom_order
    if ($wp_query->get(\'meta_key\') == \'custom_order\' && $wp_query->get(\'orderby\') == \'meta_value_num\')
    {
        $orderby = "{$wpdb->postmeta}.meta_value=\'\', ".$orderby;
    }
    return $orderby;
}
add_filter(\'posts_orderby\', \'wpse_55791_custom_orderby\', 10, 1);

5 个回复
最合适的回答,由SO网友:jessica 整理而成

指定meta\\u键时,query_posts() 在wp\\u posts和wp\\u postmeta表之间进行内部联接。这意味着,对于您指定的键,任何没有任何元值的帖子都不会在该查询中返回。

为了满足您的需要,您应该使用您在问题中发布的相同查询,但要更改orderby=meta_valueorderby=meta_value_num. 然后,您可以过滤“get\\u meta\\u sql”,使连接返回所有帖子。将以下内容添加到函数中。php:

<?php
function wpse_55791_custom_order($clauses)
{
    global $wp_query;

    // check for order by custom_order
    if ($wp_query->get(\'meta_key\') == \'custom_order\' && $wp_query->get(\'orderby\') == \'meta_value_num\')
    {
        // change the inner join to a left join, 
        // and change the where so it is applied to the join, not the results of the query
        $clauses[\'join\'] = str_replace(\'INNER JOIN\', \'LEFT JOIN\', $clauses[\'join\']).$clauses[\'where\'];
        $clauses[\'where\'] = \'\';
    }
    return $clauses;
}
add_filter(\'get_meta_sql\', \'wpse_55791_custom_order\', 10, 1);
?>
编辑:若要修复排序,请尝试将其与上述内容一起添加:

<?php
function wpse_55791_custom_orderby($orderby)
{
    global $wp_query, $wpdb;

    // check for order by custom_order
    if ($wp_query->get(\'meta_key\') == \'custom_order\' && $wp_query->get(\'orderby\') == \'meta_value_num\')
    {
        $orderby = "{$wpdb->postmeta}.meta_value=\'\', ".$orderby;
    }
    return $orderby;
}
add_filter(\'posts_orderby\', \'wpse_55791_custom_orderby\', 10, 1);
?>
编辑两个-2个循环:

我会这样做:

$paged = (get_query_var(\'paged\')) ? get_query_var(\'paged\') : 1; 
$ordered_posts = new WP_Query(array(
    \'paged\' => $paged,
    \'cat\' => 7,
    \'posts_per_page\' => 24,
    \'meta_key\' => \'custom_order\',
    \'orderby\' => \'meta_value_num\',
    \'order\' => \'ASC\',
));

$unordered = new WP_Query(array(
    \'cat\' => 7,
    \'paged\' => $paged,
    \'posts_per_page\' => 24 - $ordered_posts->post_count,
));

if ($ordered_posts->have_posts()) :
    while ($ordered_posts->have_posts()) : $ordered_posts->the_post();
    // loop 1
    endwhile;
endif;

if ($unordered_posts->have_posts()) :
    while ($unordered_posts->have_posts()) : $unordered_posts->the_post();
    // loop 2
    endwhile;
endif;
请注意,如果您认为有超过24篇已排序的文章,那么paged变量对于未排序的文章将是错误的;您可能需要设置一个全局变量来跟踪到目前为止显示了多少已排序/未排序的帖子,并使用它来计算单独的$paged 每种类型的值。

SO网友:Milo

您可以将帖子ID放入一个数组中,然后查询除这些ID之外的所有帖子:

$post_ids = array();
foreach( $wp_query->posts as $post ):
    $post_ids[] = $post->ID;
endforeach;

$args = array(
    \'posts_per_page\' => -1,
    \'post__not_in\' => $post_ids
);
$remaining = new WP_Query( $args );

SO网友:luqita

我以一种非常简单的方式解决了这个问题,使用数组进行排序,如下所示:

$posts = get_posts(array(
                    \'orderby\' => array(
                        \'meta_key\' => \'meta_key\', /* your meta key here */
                        \'meta_value\' => \'meta_value_num\',
                        \'order\' => \'DESC\',
                    )
            ));   
这应该可以解决它:)

SO网友:mitchiru

这是一个很好的解决方法,即使我一点都不喜欢。这也是wordpress查询api的局限性。在旧时代,我喜欢用mysql做这件事。。但有时会与WP发生冲突。。你知道的

//get only ordered posts
$args = array(
    \'post_type\'=>\'supporters\',
    \'order\' => \'ASC\',
    \'orderby\' => \'meta_value_num\',
    \'meta_key\' => \'wpcf-sorting\'
);
$cat_posts = new WP_Query($args);

//collect ordered post ids
$post_ids = array();
foreach( $cat_posts->posts as $post ):
    $post_ids[] = $post->ID;
endforeach;


//get only unordered posts
$args = array(
    \'post_type\'=>\'supporters\',
    \'posts_per_page\' => -1,
    \'post__not_in\' => $post_ids
);
$cat_posts_unordered = new WP_Query($args);


if ($cat_posts->have_posts() || $cat_posts_unordered->have_posts()) {   
    while ($cat_posts->have_posts()) {
        $cat_posts->the_post();

        get_template_part( \'content-supporters\', get_post_format());
    }
    while ($cat_posts_unordered->have_posts()) {
        $cat_posts_unordered->the_post();

        get_template_part( \'content-supporters\', get_post_format());
    }
}

SO网友:Langusten Gustel

就易用性而言,由于我的解决方案是针对管理面板的,所以它并不注重效率。我所做的是加载所有帖子,然后使用php对其进行排序。

function MY_PLUGIN_get_ordered_pages_by_cat_id($cat_id) {
    $all_pages = get_posts(
                array(
                    \'post_type\' => \'page\',
                    \'cat\' => $cat_id,
                    \'order\' => \'ASC\'
                )
            );

    $pages      = [];
    $page_len   = count($all_pages);
    foreach($all_pages as $page):
        $positon        = @get_post_meta($cat_id, \'_page_position\', true);
        $a_pos          = !empty($positon) ? $positon : $page_len++;
        $pages[$a_pos]  = $page;
    endforeach;
    sort($pages);
    return $pages;
}
也许这对某人有帮助。:)

结束

相关推荐

Pagination on 2nd loop

好的,我正在创建一个业务列表网站,该网站使用列表“类型”的自定义分类法。我需要在分类法归档页面上显示两个循环,一个用于“赞助”列表,另一个用于常规列表。分类法存档:http://pastie.org/3187162分页功能:http://pastie.org/3187168这两部分都在做我想做的事情,但有一个问题:在一个特定类别中大约有50个非赞助商列表,但第二个查询最多有5个“页面”(即,如果我将posts\\u per\\u page设置为5,则有25个列表,如果我将posts\\u per\\u p