【问题标题】:wordpress sticky post on archive page with pagination带有分页的存档页面上的 wordpress 粘性帖子
【发布时间】:2019-03-05 04:14:30
【问题描述】:

我有重定向到 archieve.php 的类别页面。

你可以在这里看到:https://www.dealfinder.lk/category/dining/

顶部有两个置顶帖。

1) 使用 COMBANK 卡在 &Co Pub and Kitchen 享受高达 25% 的折扣

2) 在 Robata – Movenpick Hotel Colombo,所有 HSBC 信用卡均可享受 20% 的折扣

我的分页是每篇文章 10 个条目

现在,它向我显示每个帖子 12 个项目。

这是我的代码:

function yell_category_sticky_posts( $posts, $wp_query ) {

    global $wp_the_query;

    // Don't continue if this isn't a category query, we're not in the main query or we're in the admin
    if ( ! $wp_query->is_category || $wp_query !== $wp_the_query || is_admin() )
        return $posts;

    global $wpdb;

    $q = $wp_query->query_vars;

    $page = absint( $q['paged'] );

    if ( empty( $page ) )
        $page = 1;

    $post_type = $q['post_type'];

    $sticky_posts = get_option( 'sticky_posts' );

    if ( $wp_query->is_category && $page <= 1 && is_array( $sticky_posts ) && !empty( $sticky_posts ) && ! $q['ignore_sticky_posts'] ) {

        $num_posts = count( $posts );

        $sticky_offset = 0;

        // Loop over posts and relocate stickies to the front.
        for ( $i = 0; $i < $num_posts; $i++ ) {

            if ( in_array( $posts[$i]->ID, $sticky_posts ) ) {

                $sticky_post = $posts[$i];

                // Remove sticky from current position
                array_splice( $posts, $i, 1 );

                // Move to front, after other stickies
                array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );

                // Increment the sticky offset.  The next sticky will be placed at this offset.
                $sticky_offset++;

                // Remove post from sticky posts array
                $offset = array_search( $sticky_post->ID, $sticky_posts );
                unset( $sticky_posts[$offset] );

            }

        }

        // If any posts have been excluded specifically, Ignore those that are sticky.
        if ( !empty( $sticky_posts ) && !empty( $q['post__not_in'] ) )
            $sticky_posts = array_diff( $sticky_posts, $q['post__not_in'] );

        // Fetch sticky posts that weren't in the query results
        if ( !empty( $sticky_posts ) ) {

            $stickies__in = implode( ',', array_map( 'absint', $sticky_posts ));

            // honor post type(s) if not set to any
            $stickies_where = '';

            if ( 'any' != $post_type && '' != $post_type ) {

                if ( is_array( $post_type ) )
                    $post_types = join( "', '", $post_type );

                else
                    $post_types = $post_type;

                $stickies_where = "AND $wpdb->posts.post_type IN ('" . $post_types . "')";
            }

            $stickies = $wpdb->get_results( "SELECT wp_posts.* FROM $wpdb->posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1  AND ( wp_term_relationships.term_taxonomy_id IN (" . get_term( $wp_query->query_vars['cat'], 'category' )->term_taxonomy_id . ") ) AND $wpdb->posts.ID IN ($stickies__in) $stickies_where" );

            foreach ( $stickies as $sticky_post ) {

                // Ignore sticky posts are not published.
                if ( 'publish' != $sticky_post->post_status )
                    continue;

                array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );

                $sticky_offset++;

            }
        }
    }

    return $posts;

}
add_filter( 'the_posts', 'yell_category_sticky_posts', 10, 2 );

我的问题:

我想每页显示 10 个帖子,目前它显示 12 个帖子 每页带有置顶帖。

这个问题是给大师的,不是给新手的。

这里有高手吗?提前致谢

【问题讨论】:

  • 这个老插件的源代码没有提供任何解决方案? de.wordpress.org/plugins/category-sticky-post
  • 这将非常复杂,除非您将“粘性帖子”保存在元数据中,使用该键进行查询并按其值排序(已在 wordpress.org/ideas/topic/… 中提出)。
  • @OutsourceWordPress 感谢您的回复。我已经使用了“单选按钮”元键(is_featured_post)。有单选按钮作为两个值(1 和 0)。它按照查询文档工作。我获取了 calue 1 和 0 的帖子。但我想随机发布设置为“0”的帖子。希望你能理解我的问题。
  • 好的,我会为您更新解决方案。

标签: php wordpress wordpress-theming


【解决方案1】:

以下功能将便签推到顶部,您应该可以使用它来帮助您解决问题。

add_filter('the_posts', 'bump_sticky_posts_to_top');
function bump_sticky_posts_to_top($posts) {
    $stickies = array();
    foreach($posts as $i => $post) {
        if(is_sticky($post->ID)) {
            $stickies[] = $post;
            unset($posts[$i]);
        }
    }
    return array_merge($stickies, $posts);
}

【讨论】:

    【解决方案2】:

    正如我在评论中建议的那样,将“置顶帖子”保存在 meta 中(假设 is_featured_post 为“元键”)。

    只运行一次来设置现有帖子的元值。您可以跳过此步骤,因为您已经保存在元数据中。

    // set meta value of all posts to 0
    $all_posts = get_posts(array('post_type'=>'post','posts_per_page'=>-1));
    if( is_array( $all_posts ) )
    {
        foreach( $all_posts as $post ) {
            update_post_meta( $post->ID, 'is_featured_post', '0'  );
        }
    }
    
    // set meta value of all sticky posts alone to 1
    $sticky_posts = get_option( 'sticky_posts' );
    if( is_array( $sticky_posts ) )
    {
        foreach ( $sticky_posts as $sticky_post ) {
             update_post_meta( $sticky_post, 'is_featured_post', '1'  );
        }
    }
    

    每次更新帖子(或保存新帖子)时,以下函数将更新新的粘性元is_featured_post。

    function save_sticky_meta( $post_id ) {
        if ( isset( $_REQUEST['sticky'] ) ) {
            update_post_meta( $post_id, 'is_featured_post', '1'  );
        }
        else {
            update_post_meta( $post_id, 'is_featured_post', '0'  );
        }
    }
    add_action( 'save_post', 'save_sticky_meta' );
    add_action( 'edit_post', 'save_sticky_meta' );
    

    然后使用pre_get_posts 动作设置分类查询。我们按 'meta' 和 'date' 降序排序,以在顶部显示最新的。

    function include_sticky_posts( $query ) {
        if ( ! is_admin() && $query->is_main_query() && $query->is_category() ) {
            $query->set( 'meta_key', 'is_featured_post' );
            $query->set( 'sticky_sort', true ); //custom sticky order query
            $query->set( 'orderby', 'meta_value_num date' );
            $query->set( 'order', 'DESC' );
        }
    }
    add_action( 'pre_get_posts', 'include_sticky_posts' );
    

    如果您想随机化非粘性帖子,请使用the_posts 过滤器更改顺序,如下所示。

    add_filter( 'the_posts', 'sticky_posts_sort', 10, 2 );
    function sticky_posts_sort( $posts, $query )
    {
        // if custom sort set from category query
        if ( true !== $query->get( 'sticky_sort' ) )
            return $posts; 
    
        // loop through posts & save sticky & other posts in seperate arrays
        $sticky_posts = get_option( 'sticky_posts' );
        $sticky_array = array();
        $posts_array = array();
        foreach ( $posts as $p ) {
            if( in_array( $p->ID, $sticky_posts ) )
                $sticky_array[] = $p;
            else
                $posts_array[] = $p;
        }
    
        // merge both arrays and randomize non-sticky posts alone
        if( is_array( $posts_array ) )
            shuffle( $posts_array );
        if( is_array( $sticky_array ) && is_array( $posts_array ) )
            $posts = array_merge( $sticky_array, $posts_array );
        elseif( is_array( $sticky_array ) )
            $posts = $sticky_array;
        else
            $posts = $posts_array;
    
        return $posts;
    }
    

    【讨论】:

    • 感谢您的回答。我很感激。这将解决几乎所有问题。但我希望随机列出非精选帖子的帖子。您正在使用 ('order', 'DESC') 它将按降序列出我的帖子。我想让我的帖子列表随机哪些帖子不是“精选”。我浏览了查询文档:有变量 "orderby-> rand" 。如果我使用“rand”变量,特色帖子不会首先出现。希望你能理解我的回复。谢谢
    • 是的,现在明白了,让我看看解决方案。
    • 但请注意,每页显示的非粘性帖子只会随机显示,而不是全部。
    • 感谢您更新的答案。它接近我的解决方案
    猜你喜欢
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    • 2016-04-01
    • 2013-02-09
    • 2015-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多