限制分类页面上显示的自定义帖子数量

时间:2015-08-11 作者:caffeinehigh

我正在使用一种自定义的帖子类型,它使用两种分类法“颜色”和“样式”。我有一个剧本(from this thread) 将它们分组在一起,因此当您在颜色分类页面上时,它们按样式分组,如下所示:

蓝色>样式1产品1产品2产品3产品4产品5蓝色>样式2产品1产品3产品3产品4产品5产品3产品3产品4产品4产品5产品5产品5产品2产品1产品3产品3产品3产品4产品4产品5产品5产品5产品5产品5产品5产品现在一切都很好,但每个帖子都会返回。我想限制每种风格的前三篇帖子。我知道我可以像下面这样做,但它限制了整个页面的帖子,而不是每种风格。有什么帮助吗?:)

//limit to three per style
add_action(\'pre_get_posts\', \'change_tax_num_of_posts\' );

function change_tax_num_of_posts( $wp_query ) {

    if( is_tax(\'colour\') && is_main_query() ) {

      $wp_query->set(\'posts_per_page\', 3);

    }

}

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

正如我在评论中所说,这将需要一些工作。简而言之,您将需要以下内容:

获取style 分类学这里我们只需要术语ID

获取当前tax_querycolour 分类学使用style 分类并创建新的tax_query 从当前页面的术语和从style 分类学

对中的每个术语运行自定义查询style 分类法,从每个术语中获取一个post id数组。您可以在此处添加所有自定义参数。我们将使用此自定义查询中的订单作为后订单

将post ID数组传递给主查询。在这里,您不想添加自定义排序等。我们将使用post id数组中的post id序列进行排序

代码前的几个注意事项:由于使用了短数组语法,代码需要PHP 5.4以上([]). 您也不应该使用任何早于PHP5的版本。4、如果您这样做了,只需将短数组语法更改为旧数组语法即可(array()). 例如get_terms( $taxonomy, [\'fields\' => \'ids\'] ) 应该成为get_terms( $taxonomy, array( \'fields\' => \'ids\' ) )

我已经建立了一个瞬态系统,以减少我们需要做的所有额外工作带来的额外压力。此瞬态设置为一周后过期,您可以将其调整为更长或更短。当发布、删除、取消删除或更新新帖子时,瞬态将自动删除

  • 我对代码的注释非常好,因此您可以按照我所做的来理解

    您可以根据需要进行扩展和修改。确保查看我的评论

    使用此新代码,您可以放弃我的完整排序思想,如中所述my linked answer on SO. 此答案中给出的代码应负责此排序。您想要进行的任何调整都应该在自定义查询和get_terms 呼叫。只要记住在每次修改后刷新瞬态,或者最好取消对瞬态调用的注释,并在对所有修改满意后恢复正常

    代码:一如既往,我们将使用pre_get_posts 根据需要更改主查询

    add_action( \'pre_get_posts\', function ( $q )
    {       
        if (    !is_admin() // Targets only front end queries
             && $q->is_main_query() // Targets only main query
             && $q->is_tax( \'colour\' ) // Targets only taxonomy pages
        ) {
    
            /** 
             * To save on the extra work that we need to do to get our results,
             * lets save everything in a transient. We will save the string of post ids
             * in the transient. 
             *
             * We will only delete and recreate this transient when a new post is published,
             * deleted, undeleted or updated. This will save us a lot of extra hard work
             * on every page load
             *
             * @link https://codex.wordpress.org/Transients_API
             */
            $queried_object = get_queried_object(); // Get the current queried object to build a unique transient name
            /**
             * Use md5 to build a unique transient name to avoid any conflicts
             * The code below will create a unique transient name which will look like this
             * "colourtax_1ac37e97ee207e952dfc2b8f7eef110f"
             *
             * Note, this should NOT be longer that 45 characters else the transient will be regenerated
             * on each page load. Transients are expensive to create, so don\'t want to recreate this on every
             * page load due to a name being to long. As a quick guide the md5 part generate a 32 character string,
             * so the "colourtax_" part should be a maximum of 13 characters
             */
            $unique_transient_name = \'colourtax_\' . md5( $queried_object->taxonomy . $queried_object->slug . $queried_object->term_id );
            if ( false === ( $post_ids_array = get_transient( $unique_transient_name ) ) ) {
    
                // Gets the current tax_query
                $tax_query = $q->tax_query->queries; 
                // Choose the taxonomy to sort by
                $taxonomy = \'style\'; 
                // Set the variable to hold the sorted post ids according to terms
                $post_ids_array = [];
    
                /**
                 * Get all the terms from the selected taxonomy to sort by. Just get term ids
                 * Add additional arguments here as needed
                 * 
                 * @link https://codex.wordpress.org/Function_Reference/get_terms
                 */
                $terms = get_terms( $taxonomy, [\'fields\' => \'ids\'] ); 
                if (    $terms // Check if the array has valid terms, not empty
                     && !is_wp_error( $terms ) // Check that we do not have any error
                ) { 
                    // Define a variable to hold all post ID
                    $posts_ids = \'\';
                    foreach ( $terms as $term ) {
                        /**
                         * NOTE: You would want to do everything here
                         *
                         * Build our query args, add all your relevant arguments here
                         * You should extend this to include your custom parameter values
                         * like meta_queries en sorting order.
                         * Do a var_dump( $wp_query ) and use the relevant arguments from
                         * there to make this dynamic
                         */
                        $args = [
                            \'post_type\' => \'any\',
                            \'posts_per_page\' => 3, // Get only 3 posts per term
                            \'fields\' => \'ids\', // Only get post ids to make query faster and more lean
                            // Build a tax_query to add additional terms from selected taxonomy to sort by  
                            \'tax_query\' => [ 
                                $tax_query, // Our default tax_query from the taxonomy page
                                [
                                    \'taxonomy\' => $taxonomy,
                                    \'terms\' => $term,
                                    \'include_children\' => false,
                                ],
                            ],
                        ];
                        // Return an array of post ids only
                        $posts_array = get_posts( $args );
                        // First check if we have posts to avoid bugs in our code
                        if ( $posts_array ) {
                            // Break the ids array up into a string for later processing
                            foreach ( $posts_array as $v )
                                $posts_ids .= \' \' . $v;
                            unset( $v );    
                        } //endif $posts_array
    
                    } //endforeach $terms
                    unset( $term );
    
                    // ADDITIONAL, CAN DELETE THE FOLLOWING SECTION IF YOU WANT TO. READ COMMENTS BELOW
    
                    /**
                     * You can remove the following section. The idea here is as follow:
                     * Any post without a term in the style taxonomy will not be displayed on
                     * a colour taxonomy term page. To avoid this, we will need to get all posts
                     * that does not have a post in style taxonomy. This posts will be displayed last
                     * on the page
                     *
                     * If you are very sure that all posts are tagged in a colour AND style taxonomy
                     * term, then you can remove this section, this is really just a fall back
                     */
                    $args_additional = [
                        \'post_type\' => \'any\',
                        \'posts_per_page\' => 3, // Get only 3 posts without style taxonomy term, adjust as needed
                        \'fields\' => \'ids\', // Only get post ids to make query faster and more lean
                        // Build a tax_query to get posts that is not tagged in style taxonomy  
                        \'tax_query\' => [ 
                            $tax_query, // Our default tax_query from the taxonomy page
                            [
                                \'taxonomy\' => $taxonomy,
                                \'terms\' => $terms,
                                \'include_children\' => false,
                                \'operator\' => \'NOT IN\', // Posts should not have these terms from style taxonomy
                            ],
                        ],
                    ];
                    // Return an array of post ids only
                    $posts_array_2 = get_posts( $args_additional );
                    // First check if we have posts to avoid bugs in our code
                    if ( $posts_array_2 ) {
                        // Break the ids array up into a string for later processing
                        foreach ( $posts_array_2 as $v )
                            $posts_ids .= \' \' . $v;
                        unset( $v );    
                    } //endif $posts_array
    
                    // STOP DELETING HERE!!
    
                    // Create an array of post ids from the $posts_ids string
                    $post_ids_array = explode( \' \', ltrim( $posts_ids ) );
    
                } //endif $terms
    
                /**
                 * Set the transient if it does not exist. 
                 * NOTE: We will choose a week for expiry date, set as needed
                 *
                 * @link https://codex.wordpress.org/Transients_API#Using_Time_Constants
                 */     
                set_transient( $unique_transient_name, $post_ids_array, 7 * DAY_IN_SECONDS );   
            } // endif transient check
    
            /**
             * Check if we have an array of post ID\'s before changing anything on the tax page
             *
             * Here we will alter the main query. You do not want to add or remove anything
             * here. Any custom parameters like sorting should be done in the custom queries
             * above
             *
             * DO NOT CHANGE ANYTHING IN THE CODE BELOW EXCEPT posts_per_page
             */
            if ( !empty( $post_ids_array ) ) {
                $q->set( \'post__in\', $post_ids_array ); // Posts to get as set in our array, max of 3 posts per term
                $q->set( \'orderby\', \'post_in\' ); // Sort our posts in the order it is passed in the post__in array
                $q->set( \'order\', \'ASC\' );
                $q->set( \'posts_per_page\', -1 ); // You can change this, if I remember, you need all posts on one page
            }
    
        } //endif conditional checks for query
    });
    
    这将处理除发布后刷新、删除等瞬态之外的所有事情

    以下代码将处理此问题。每当一篇帖子被更新、发布、垃圾或未经处理时transition_post_status 钩子激发,所以我们将使用该逻辑删除所有包含colourtax_ 名称

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

  • SO网友:caffeinehigh

    好的,我想我已经找到了一种方法。虽然我必须说,我还没有测试出来,这可能不是最好的方法。很高兴看到其他解决方案。

    我所做的是在我的自定义帖子中创建一个元框,其中有一个单选按钮,可以选择“特色”和“不特色”。我设置了要显示的每个组的三个自定义帖子,然后用匹配的元键过滤主查询。像这样:

    function colour_tax_featured($query) {
    
    if( is_tax(\'colour\') && $query->is_main_query() ) {
    
        $query->set(\'meta_key\', \'meta_box_featured_colour\');
            $query->set(\'meta_value\', \'featured_colour\');
        return $query;
    }
    
     }
    
        add_action(\'pre_get_posts\', \'colour_tax_featured\' );
    

    结束

    相关推荐

    Global functions on WPMU

    我在一个多站点环境中工作,所有站点都是相关的。最近的许多发展都要求我将某些功能复制并粘贴到许多不同的主题文件夹中,如果我需要到处更新它们,就会出现问题。拥有全局“functions.php”文件的最佳方式是什么?我的想法是要么在themes文件夹中包含一个文件并包含它,要么创建一个插件并启用该插件。