Order post by taxonomy

时间:2015-08-25 作者:Amen Ra

我正在尝试编写一个get\\u posts()查询来检索每页7篇文章。这些帖子的检索基于3个不同的标签,“特色”、“突出显示”和“新闻”。现在,“特色”帖子优先于所有其他帖子,因此如果有7篇特色帖子,那么页面上只应显示这些帖子。就重要性顺序而言,“突出显示”的帖子排在第二位。因此,如果有2个“特色”帖子和5个“突出显示”帖子,那么应该显示这些帖子。最后,剩下的“新闻”是按重要性顺序显示帖子的最终标签名称。

以下是我目前掌握的情况:

public function automate_posts_to_send(){
    $value = get_option( \'email_settings_options\');
    $article_number = $value[\'number_of_articles_to_send\'];
    $posts = get_posts( array(
        "tag__in"          => array(135, 239, 256),
        "orderby"           => \'tag__in\',
        \'date_query\'        => array(
                array(
                    \'after\' => \'24 hours ago\'
                ),
            ),
        "posts_per_page"    => $article_number
    ) );
    return $posts;
}
我正在拿名单,但邮购顺序不对。我希望帖子按以下标签排序:特色、突出显示、新闻

3 个回复
SO网友:Pieter Goosen

这很容易实现。你的答案是usort()

几点注意事项:

在编写代码之前,只需几点注意事项

需要PHP5。4+由于使用了短数组语法([]). 如果您有一个旧版本,您应该真正升级,因为旧版本是一个真正的安全威胁,因为PHP 5.4之前的所有旧版本都已过时

我将在编写过程中对代码进行注释,以便您轻松地理解

分类术语和自定义字段是缓存的,因此您不会进行额外的db调用,因此解决方案仍然非常精简。

下面的代码未经测试,因此请确保先在本地进行测试

代码:

public function automate_posts_to_send()
{
    $value          = get_option( \'email_settings_options\');
    $article_number = $value[\'number_of_articles_to_send\'];

    /**
     * Add the tag ids here in the correct order you need your posts to be in
     * In this example, posts from tag 2 will show first, then posts from tag 3 then tag 1
     * As I said, I\'m using short array syntax, so for older versions of PHP prior to 5.4,
     * [2, 3, 1] would become array( 2, 3, 1 )
     */
    $tag_order = [2, 3, 1]; 
    $args = [ 
        \'tag__in\' => $tag_order,
        //\'orderby\' => $tag_order // This is invalid ordering, add valid value here according to needs
        \'posts_per_page\' => $article_number,
        \'date_query\' => [
            [
                \'after\' => \'24 hours ago\'
            ]
        ],
    ];
    $posts_array = get_posts( $args );

    /**
     * Now we will sort the returned array of posts as we need them according to $tag_order. We will use usort()
     *
     * There is a bug in usort causing the following error:
     * usort(): Array was modified by the user comparison function
     * @see https://bugs.php.net/bug.php?id=50688
     * This bug has yet to be fixed, when, no one knows. The only workaround is to suppress the error reporting
     * by using the @ sign before usort
     */
    @usort( $posts_array, function ( $a, $b ) use ( $tag_order )
    {
        // Store our post ids in an array. We will use that to get our post tags per post
        $array = [
            \'a\' => $a->ID, // Use only post ID
            \'b\' => $b->ID // Same as above
        ];
        // Define our two variables which will hold the desired tag id
        $array_a = [];
        $array_b = [];

        // We will now get and store our post tags according to the tags in $tag_order
        foreach ( $array as $k=>$v ) {
            $tags = get_the_tags( $v );
            if ( $tags ) {
                foreach ( $tags as $tag ) {
                    if ( !in_array( $tag->term_id, $tag_order ) )
                        continue;

                    // If we found a tag that is in the $tag_order array, store it and break the foreach loop
                    ${\'array_\' . $k}[] = $tag->term_id; // Will produce $array_a[] = $tag->term_id or $array_b[] = $tag->term_id

                    // If we found the tag we are looking for, break the foreach loop
                    break;
                } // endforeach $tags
            } // endif $tags
        } // endforeach $array

        // Flip the $tag_order array for sorting purposes
        $flipped_tag_order = array_flip( $tag_order );

        /**
         * Lets sort our array now
         *
         * We will sort according to tag first. If the tags between two posts being compared are the same
         * we will sort the posts by post date. Adjust this as necessary
         */
        if ( $flipped_tag_order[$array_a] != $flipped_tag_order[$array_b] ) {
            return $flipped_tag_order[$array_a] - $flipped_tag_order[$array_b];
        } else {
            return $a->post_date < $b->post_date; // Change to > if you need oldest posts first
        }
    }); // end our usort ordering

    // We are done sorting, etc. Return our $posts_array
    return $posts_array;
}

SO网友:vancoder

中的tag\\uu未列为中的有效orderby值the codex.

我建议抓取比您需要的更多的帖子,并在您的PHP中进行排序。

SO网友:Manny Fleurmond

默认情况下,WP不按分类法/标记排序。一种可能的解决方案是执行3个单独的get\\u posts调用,每个标记一个,然后使用array\\u merge将结果合并到一个数组中。

相关推荐

ORDER BY带有‘EXISTS’和‘NOT EXISTS’的嵌套命名元查询

我的每个帖子(在线商店项目)都有元键:tdlrm_mp - 我自己的menu\\u位置(从1开始,与wp\\u posts menu\\u位置不同,可能不存在)1C_quantity_total - 库存商品数量我希望商品按以下顺序输出:首先tdlrm_mp 存在,排序人tdlrm_mp 从最低到最高tdlrm_mp 不存在,订购者1C_quantity_total, 从高到低以下是我的元查询的参数:$args[\'meta_query\'] = array( \'