如何定义多个类别的职位编号

时间:2015-10-24 作者:soft dev

我的参数数组:

$args = array (
    \'cat\' => \'1,3,7\',
    \'posts_per_page\' => \'30\'
);
如何定义posts_per_page:

第一类:7个职位,

第3类:10个职位,

第7类:13个职位,

2 个回复
SO网友:Eduardo Sánchez Hidalgo Urías

我不知道是否有类似的东西posts_per_category"cat" => array( "5" => array("posts_per_page" => "3"), 但如果使用posts-id形成一个数组,则可以使用条件语句来实现。我能看到的问题是,你必须查询所有帖子或设置一个日期限制,例如,但会这样做。

Edit: @彼得·古森让我更多地思考这个问题。他关于wp_get_post_categories(); 但是还有其他方法可以获得类别id,我把它留给你。但是稍微考虑一下,如果您可以在if语句中直接打印任何您想要的内容,那么就没有必要先形成一个数组,然后再调用post。

<?php

$args = array ( \'cat\' => \'1,2,3\', \'posts_per_page\' => \'-1\', );

$query = new WP_Query($args);

$cat_1 = 0;
$cat_2 = 0;
$cat_3 = 0;
if($query->have_posts()) {
    while($query->have_posts()) {
        $query->the_post();
        $post_category = wp_get_post_categories(); //Returns an arry with all the categories ids where the post belogs
        $category_posts = [];  //After edit it is only for knowing which posts have been printed yet        
        //Get all posts ids in a general array and count how many you have inserted from each category
        if (in_array( 1, $post_category) && !in_array($category_posts) $cat_1 <= 8) {
            echo "<div class=\'post-title\'>";
            the_title();
            echo "</div>";
            $category_posts[] = get_the_ID();
            $cat_1++;
        }

        if (in_array( 2, $post_category) && !in_array($category_posts) $cat_2 <= 10) {               echo "<div class=\'post-title\'>";
            the_title();
            echo "</div>";

            $category_posts[] = get_the_ID();
            $cat_2++;
        } 

        if (in_array( 3, $post_category) && !in_array($category_posts) && $cat_3 <= 17 ) {
            echo "<div class=\'post-title\'>";
            the_title();
            echo "</div>";
            $category_posts[] = get_the_ID();
            $cat_3++;
        }

    }
}

//$cat_n is for the number of posts you want from each category
Edited: (编辑后不需要这样做)

那你就得绕着槽走$category_posts 数组以获取ID并在while循环外打印所需的任何内容。

我在飞行中做了这个,所以它可能有一些错误,但这是一般的想法。

在本例中,如果相同的帖子属于这两个类别,那么它将计算带有次要编号的类别,而不计算另一个类别,即!in_array($category_posts) 对于

SO网友:Pieter Goosen

没有本机方法可以实现这一点,因此需要运行多个查询才能实现这一点。如果做得不正确,这可能会变得非常昂贵,因此我们需要在这里保持聪明。

我在这里想到了一些想法,这似乎是有道理的,所以下面是我们将要做的

为每个学期运行一个查询,以获取每个学期我们想要的帖子数量。为了尽可能精简,并真正节省db调用和时间,我们将只获取post ID

从所有这些查询中,我们将构建一个ID数组。如果一篇文章属于两个术语,我们还需要删除重复项

一旦我们有了一个post ID数组,我们将运行最终查询以获得完整的post对象

我决定创建一个函数来收集帖子ID,然后在一个瞬态中保存所有内容,每当创建新帖子,或者更新、删除或取消删除帖子时,我们都会刷新该瞬态。这样,您可以使查询更加精简。在一天结束时,该函数在不到0.005s的时间内只需要2个db调用,因此它在性能方面确实更有意义

函数中的所有内容都有很好的注释,因此请确保在进行过程中遵循注释:(NOTE: 此答案中的所有代码至少需要PHP 5.4)

/**
 * Function to get an array of post ID\'s according to term and according
 * to a specific amount of posts per page set per term
 *
 * @param (string) $post_type
 * @param (string) $taxonomy
 * @param (array)  $args
 * @return (array) $output_ids
 */
function get_unique_ppp_per_category( $post_type = \'post\', $taxonomy = \'category\', $args = [] )
{
    // Make sure we have a post type and taxonomy and sanitize it
    if (    !$post_type
         || !$taxonomy
    )
        return false;

    if ( $post_type !== \'post\' )
        $post_type = filter_var( $post_type, FILTER_SANITIZE_STRING );

    // Make sure we have a valid taxonomy to avoid bugs
    if (    $taxonomy !== \'category\'
         || $taxonomy !== \'post_tag\'
    ) {
        // Santitize and validate the taxonomy
        $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );

        // Check if taxonomy exist, if not, return false
        if ( !taxonomy_exists( $taxonomy ) )
            return false;
    }

    // If $args are empty or not an array, return false
    if (    !$args
         || !is_array( $args )
    ) {
        return false;
    }

// Set a transient to store the post ID\'s. Excellent for performance
    if (    false === ( $output_ids = get_transient ( \'term_id_list_\' . md5( $post_type . $taxonomy . json_encode( $args ) ) ) ) ) {
        // Set up a variable to hold an array of post id and id that should not be duplicated
        $post_ids = [];

        /**
         * Loop through the $args array and build our queries
         *
         * We need to make sure that every value, $arg, is an array.
         * That array should have the term id as key and posts per page value
         * as value, so in short, the setup should be \'(int) term ID => (int) posts_per_page\'
         * If not, we will simply continue. You should however build in some kind of
         * error notice on this as it can and will make debugging easier
         */
        foreach ( $args as $term_id=>$ppp ) {
            // Sanitize and validate our values
            $ppp     = filter_var( $ppp,     FILTER_VALIDATE_INT );
            $term_id = filter_var( $term_id, FILTER_VALIDATE_INT );

            /**
             * Create a flat array of post ID\'s that we should not duplicate
             *
             * @see array_walk_recursive
             */
            $duplicates = [];
            if ( $post_ids ) {
                array_walk_recursive( $post_ids, function ( $a ) use ( &$duplicates )
                {
                    $duplicates[] = $a;
                });
            }

            // Set up our query args
            $query_args = [
                \'fields\'         => \'ids\', // Get only post ids to make this very quick
                \'post_type\'      => $post_type,
                \'posts_per_page\' => $ppp,
                \'post__not_in\'   => $duplicates, // Do not duplicate these posts
                \'tax_query\'      => [
                    [
                        \'taxonomy\'         => $taxonomy,
                        \'terms\'            => $term_id,
                        \'include_children\' => false
                    ]
                ],
                // Add any extra parameters here
            ];
            $q = get_posts( $query_args );

            $post_ids[] = $q;
        } // endforeach $args

        /**
         * Flattern the nested array of post ID\'s
         *
         * @see array_walk_recursive
         */
        $output_ids = [];
        if ( $post_ids ) {
            array_walk_recursive( $post_ids, function ( $a ) use ( &$output_ids )
            {
                $output_ids[] = $a;
            });
        }

        set_transient( \'term_id_list_\' . md5(  $post_type . $taxonomy . json_encode( $args ) ), $output_ids, 30*DAY_IN_SECONDS );
    }   

    return $output_ids;
}
用法根据示例,您需要类别1中的7篇帖子、类别3中的10篇帖子和类别7中的13篇帖子。该函数有三个参数,第一个是post类型,第二个是分类法,第三个是键/值对数组,其中键是类别ID,值是特定类别的post数量

因此,在本例中,我们将使用内置类型post 以及内置分类法category

EXAMPLE

$args = [
    //\'category ID\' => \'posts_per_page\',
    1 => 7,
    3 => 10,
    7 => 13
];
$q = get_unique_ppp_per_category( \'post\', \'category\', $args );
var_dump( $q );
现在我们可以通过$q 到适当的WP_Query. 在我们做之前只需要做几点笔记

如果您需要在将类别传递给get_unique_ppp_per_category 函数,则需要设置orderby 中的参数WP_Querypost__in

记住,如果你的帖子类型不是post, 记住设置post_type 以及参数

现在让我们来完成我们的帖子

if ( $q ) {
    $query_args = [
        \'post__in\'       => $q,
        \'posts_per_page\' => -1,
        \'orderby\'        => \'post__in\',
        \'order\'          => \'ASC\'
    ];
    $the_query = new WP_Query( $query_args );
    while ( $the_query->have_posts() ) {
    $the_query->the_post();

        // Your template tags and html markup, like
        the_title();

    } // endwhile
    wp_reset_postdata();
} // endif $q
我们只剩下在发布新帖子或删除、取消删除或更新帖子时刷新瞬态。我们将使用transition_post_status 适合账单的钩子

add_action( \'transition_post_status\', function ()
{
    global $wpdb;
    $wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient%_term_id_list_%\')" );
    $wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient_timeout%_term_id_list_%\')" );
});