静态首页上的WP_QUERY和分页

时间:2015-04-23 作者:Morklympious

在过去的两天里,我一直在尝试调试一个问题WP_Query() 和分页。

我开发的一个网站使用了Wordpress主题(由ThemeNectar突出),其中包括visual composer插件。我的工作本质上是确保网站正常运行,所以不久前我为visual composer编写了一个扩展。此扩展使用WP_Query() 要创建新查询,请在特定类别中查找帖子(建立默认类别),然后返回该查询的输出

下面是在visual composer组件中呈现帖子和分页的代码

public function renderPosts( $atts, $content = null ) {
    global $post;
    setup_postdata($post);

     extract( shortcode_atts( array(
            \'foo\' => 5, //default of 5
            \'categoryslug\' => \'news-views\' // Currently news and views.
    ), $atts) );

    // For getting the Query variable on a statcci front page, you have
    // to use \'page\' and not \'paged\'. Weird.          
    $paged = ( get_query_var(\'page\') ) ? get_query_var(\'page\') : 1;


    // Two things needed: Not using the game library,
    // Definitely using the supplied slug.
    // These are two objects.

    $dontUse = get_category_by_slug(\'game-library\');
    $catUsed = get_category_by_slug($atts->categoryslug);

    // Args for the custom query
     $query_args = array(
       \'posts_per_page\'   => intval($foo),
       \'category__not_in\' => $dontUse->term_id,
       \'cat\' => $catUsed->term_id,
       \'page\' => $paged
     );

    $custom_query = new WP_Query($query_args);                      

            $output = \'<div id="blogroll">\';  
            while ( $custom_query->have_posts() ) : $custom_query->the_post();

                $output .= "<div class=\'home_post col span_12 clear-both\'>";
                $output .=      "<div class=\'col span_3\'><a href=\'" . get_the_permalink() . "\'>" . get_the_post_thumbnail(get_the_ID(), \'home_post_thumb\') . "</a></div>";
                $output .=      "<div class=\'col span_9 col_last right-edge\'>";
                $output .=        "<h2 class=\'home_post_header\'>";
                $output .=           \'<a href="\' . get_the_permalink() . \'">\' . get_the_title() . "</a>";
                $output .=        "</h2>";
                $output .=        get_the_excerpt();
                $output .=      \'<a class="home-more-link" href="\' . get_the_permalink() . \'"><span class="continue-reading">Read More</span></a>\';
                $output .=      "</div>";
                $output .= "</div>";

            endwhile;

            wp_reset_postdata();

            // Pagination not working, but it outputs just fine?
            $output .= \'<div id="pagination" class="blogroll-pagination">\' . home_pagination($custom_query) . \'</div></div>\';
            wp_reset_query();              

            return $output;  
 }
现在,我知道生成内容的代码只是一个巨大的串联字符串,但这只是因为扩展函数必须返回一些东西。最后,我使用上面定义的另一个函数输出分页。

Here\'s the function 我创建了呼叫home_pagination(query)

function home_pagination($query = null) {
    /*if ( !$query ) {
            global $wp_query;
            $query = $wp_query;
    } commented out because do I need this? */

    $big = 999999999; // need an unlikely integer

    $pagination = paginate_links( array(
            \'base\' => str_replace( $big, \'%#%\', esc_url( get_pagenum_link( $big ) ) ),
            \'format\' => \'?paged=%#%\',
            \'current\' => max( 1, get_query_var( \'page\' ) ),
            \'total\' => $query->max_num_pages,
            \'prev_text\' => \'&laquo; Previous\',
            \'next_text\' => \'Next &raquo;\',

            ) );

    return $pagination;

} 
现在,这个功能在一周前还没有发挥作用,但我现在似乎无法让它发挥作用。。。以下是我尝试过的:

玩弄get_query_var(\'page\')

  • 使用插件(Wp\\u page\\u navi)
  • 更改位置和时间wp_reset_postdata()wp_reset_query() 使用max_num_pages 解决方法next_posts_link()previous_posts_link()static front page 我知道“页面”和“页面”的规则是不同的

    Interesting to note: 当我在查询参数中更改“paged”变量时,它会返回正确的对应页面。

    我试图弄清楚为什么我在尝试导航时,作为此查询一部分输出的分页完全没有任何作用?这就好像它想导航到/page/2或任何数字,但随后立即重定向到网站本身。。。

    我在考虑不把paginate_links() 调用一个单独的函数。可能有一些明显的错误,但我一直在努力进行分页,似乎不再有效。关于我如何才能最好地解决这个问题,有什么想法吗?我有没有遗漏什么大东西?

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

    我不太清楚你所说的扩展视觉作曲家是什么意思,但我确实有几个问题。

    • SoC -> 从您的代码中,我发现您正在使用一个短代码,它应该有自己的独立类。您不应该将该类扩展到可视化编辑器(至少我是这样理解您的问题的)。课程不应该有多个任务,他们应该这样做one 单一负载。这使您的类保持可扩展、简短、易于维护、可重用和易于测试

      扩展前一点,前端和后端功能不应混用

      我看不出使用global $post 以及设置post数据。执行此操作并且之后不重置postdata将对之后的任何查询和主查询产生意外影响。你应该彻底放弃

      永远不要使用extract() 在短代码中(以及任何其他函数)。这是非常不可靠和不稳定的,并导致意外的输出。这使得在出现故障时进行调试变得极其困难。正是由于这个原因,它被完全从核心中移除。看见trac ticket 22400

      因为您使用了多个类别条件,为了使其更具动态性,我宁愿使用tax_query 处理这些情况。这里最大的好处是,您可以节省db调用,因为您可以摆脱get_category_by_slug

      没有必要wp_reset_query(). 此选项用于query_posts 你永远不应该使用它。这是一个分页符。

      首页和单页使用查询变量page (get_query_var( \'page\' )) 用于分页,而不是paged (get_query_var( \'paged\' )) 与其他页面一样。的查询参数WP_Query 但两者都是一样的,应该是paged, 不page. 这个valuepaged 参数/参数应为page 对于静态首页和paged 对于所有其他页面

    您可以按如下方式重写上述方法:(警告:未测试)

    public function renderPosts( $atts ) 
    {
        $attributes = shortcode_atts( array(
            \'foo\'     => 5, //default of 5
            \'include\' => \'news-views\', // Currently news and views.
            \'exclude\' => \'game-library\' // Exclude this category
        ), $atts);
    
        /* 
         * For getting the Query variable on a static front page, you have
         * to use \'page\' and not \'paged\'. Weird.
         */ 
        if ( get_query_var(\'paged\') ) {
            $paged = get_query_var(\'paged\'); 
        } elseif ( get_query_var(\'page\') ) { 
            $paged = get_query_var(\'page\'); 
        } else { 
            $paged = 1; 
        }
    
    
        /*
         * Args for the custom query
         */
        $query_args = array(
            \'posts_per_page\' => intval($attributes[\'foo\']),
            \'tax_query\'      => array(
                array(
                    \'taxonomy\' => \'category\',
                    \'field\' => \'slug\',
                    \'terms\' => explode( \',\', str_replace( \' \', \'\', $attributes[\'include\'] ) ),
                    \'include_children\' => false
                ),
                array(
                    \'taxonomy\' => \'category\',
                    \'field\' => \'slug\',
                    \'terms\' => explode( \',\', str_replace( \' \', \'\', $attributes[\'exclude\'] ) ),
                    \'operator\' => \'NOT IN\'
                )
            ),
            \'paged\' => $paged
        );
    
        $custom_query = new WP_Query($query_args); 
    
        $output = \'\';
        if ( $custom_query->have_posts() ) {  
    
            $output .= \'<div id="blogroll">\'; 
    
            while ( $custom_query->have_posts() ) { 
    
                $custom_query->the_post();
    
                $output .= "<div class=\'home_post col span_12 clear-both\'>";
                $output .=      "<div class=\'col span_3\'><a href=\'" . get_the_permalink() . "\'>" . get_the_post_thumbnail(get_the_ID(), \'home_post_thumb\') . "</a></div>";
                $output .=      "<div class=\'col span_9 col_last right-edge\'>";
                $output .=        "<h2 class=\'home_post_header\'>";
                $output .=           \'<a href="\' . get_the_permalink() . \'">\' . get_the_title() . "</a>";
                $output .=        "</h2>";
                $output .=        get_the_excerpt();
                $output .=      \'<a class="home-more-link" href="\' . get_the_permalink() . \'"><span class="continue-reading">Read More</span></a>\';
                $output .=      "</div>";
                $output .= "</div>";
    
            }
    
            wp_reset_postdata();
    
            $output .= \'<div id="pagination" class="blogroll-pagination">\' . home_pagination( $custom_query ) . \'</div></div>\';
    
        }
    
        return $output;  
    }
    
    请记住,我已经更改了可读性的属性,include 采用逗号分隔的类别字符串slugsinclude=\'slug-1, slug-2\')。此属性将用于包括类别。exclude 工作原理相同(exclude=\'slug-1, slug-2\'),但它采用逗号分隔的类别字符串slugs

    编辑

    我已经测试了我的代码并修复了几个小错误。如果我只是从它创建一个普通的短代码,它就会像预期的那样工作。

    概念验证-短代码

    add_shortcode( \'testcode\', function ( $atts )
    {
        $attributes = shortcode_atts( array(
            \'foo\'     => 5, //default of 5
            \'include\' => \'news-views\', // Currently news and views.
            \'exclude\' => \'game-library\' // Exclude this category
        ), $atts);
    
        /* 
         * For getting the Query variable on a static front page, you have
         * to use \'page\' and not \'paged\'. Weird.
         */ 
        if ( get_query_var(\'paged\') ) {
            $paged = get_query_var(\'paged\'); 
        } elseif ( get_query_var(\'page\') ) { 
            $paged = get_query_var(\'page\'); 
        } else { 
            $paged = 1; 
        }
    
    
        /*
         * Args for the custom query
         */
        $query_args = array(
            \'posts_per_page\' => intval($attributes[\'foo\']),
            \'tax_query\'      => array(
                array(
                    \'taxonomy\' => \'category\',
                    \'field\' => \'slug\',
                    \'terms\' => explode( \',\', str_replace( \' \', \'\', $attributes[\'include\'] ) ),
                    \'include_children\' => false
                ),
                array(
                    \'taxonomy\' => \'category\',
                    \'field\' => \'slug\',
                    \'terms\' => explode( \',\', str_replace( \' \', \'\', $attributes[\'exclude\'] ) ),
                    \'operator\' => \'NOT IN\'
                )
            ),
            \'paged\' => $paged
        );
    
        $custom_query = new WP_Query($query_args); 
    
        $output = \'\';
        if ( $custom_query->have_posts() ) {  
    
            $output .= \'<div id="blogroll">\'; 
    
            while ( $custom_query->have_posts() ) { 
    
                $custom_query->the_post();
    
                $output .= "<div class=\'home_post col span_12 clear-both\'>";
                $output .=      "<div class=\'col span_3\'><a href=\'" . get_the_permalink() . "\'>" . get_the_post_thumbnail(get_the_ID(), \'home_post_thumb\') . "</a></div>";
                $output .=      "<div class=\'col span_9 col_last right-edge\'>";
                $output .=        "<h2 class=\'home_post_header\'>";
                $output .=           \'<a href="\' . get_the_permalink() . \'">\' . get_the_title() . "</a>";
                $output .=        "</h2>";
                $output .=        get_the_excerpt();
                $output .=      \'<a class="home-more-link" href="\' . get_the_permalink() . \'"><span class="continue-reading">Read More</span></a>\';
                $output .=      "</div>";
                $output .= "</div>";
    
            }
    
            wp_reset_postdata();
    
            $output .= \'<div id="pagination" class="blogroll-pagination">\' . home_pagination( $custom_query ) . \'</div></div>\';
    
        }
    
        return $output;  
    });
    
    我使用如下

    [testcode include=\'testslug-1, testslug-2\' exclude=\'testslug-3, testslug-4\']
    
    我也测试了您的分页功能,它也按预期工作。

    function home_pagination( $query = null ) 
    {
    
        $big = 999999999; // need an unlikely integer
    
        if ( get_query_var(\'paged\') ) {
            $paged = get_query_var(\'paged\'); 
        } elseif ( get_query_var(\'page\') ) { 
            $paged = get_query_var(\'page\'); 
        } else { 
            $paged = 1; 
        }
    
    
        $pagination = paginate_links( 
            array(
                \'base\'      => str_replace( $big, \'%#%\', esc_url( get_pagenum_link( $big ) ) ),
                \'format\'    => \'?paged=%#%\',
                \'current\'   => $paged,
                \'total\'     => $query->max_num_pages,
                \'prev_text\' => \'&laquo; Previous\',
                \'next_text\' => \'Next &raquo;\',
            ) 
        );
    
        return $pagination;
    
    } 
    
    编辑你的评论,正如我已经说过的,静态首页和单页使用get_query_var( \'page\' ) 用于分页,而所有其他用途get_query_var( \'paged\' ). 我已经用以下代码更新了上面的所有代码

    if ( get_query_var(\'paged\') ) {
        $paged = get_query_var(\'paged\'); 
    } elseif ( get_query_var(\'page\') ) { 
        $paged = get_query_var(\'page\'); 
    } else { 
        $paged = 1; 
    }
    
    这将对问题进行排序pagepaged 并使您的短代码和分页可以在所有页面上工作,而无需对其进行任何特定更改

    编辑3

    Here is a sligtly modified version of the code by @ChipBennet 这将解决以下问题/page/2

    function home_pagination( $query = null ) 
    {
        global $wp_rewrite;
    
        if ( get_query_var(\'paged\') ) {
            $paged = get_query_var(\'paged\'); 
        } elseif ( get_query_var(\'page\') ) { 
            $paged = get_query_var(\'page\'); 
        } else { 
            $paged = 1; 
        }
    
    
        $pagination = array(            
            \'base\'      => @add_query_arg( \'paged\', \'%#%\' ),
            \'format\'    => \'\',
            \'current\'   => $paged,
            \'total\'     => $query->max_num_pages,
            \'prev_text\' => \'&laquo; Previous\',
            \'next_text\' => \'Next &raquo;\',
        );
    
        if ( $wp_rewrite->using_permalinks() )
            $pagination[\'base\'] = user_trailingslashit( trailingslashit( remove_query_arg( \'s\', get_pagenum_link( 1 ) ) ).\'/%#%/\', \'\' );
    
        if ( ! empty( $wp_query->query_vars[\'s\'] ) )
            $pagination[\'add_args\'] = array( \'s\' => get_query_var( \'s\' ) );
    
        return paginate_links( $pagination );
    } 
    

    SO网友:Vikram

    根据codex

    如果静态首页上的分页被破坏,则必须通过以下方式添加“paged”参数:

    if ( get_query_var(\'paged\') ) { $paged = get_query_var(\'paged\'); }
    elseif ( get_query_var(\'page\') ) { $paged = get_query_var(\'page\'); }
    else { $paged = 1; }
    
    query_posts(\'posts_per_page=3&paged=\' . $paged); 
    
    Page参数更改为Paged,更新功能代码如下

    public function renderPosts( $atts, $content = null ) {
        global $post;
        setup_postdata($post);
    
         extract( shortcode_atts( array(
                \'foo\' => 5, //default of 5
                \'categoryslug\' => \'news-views\' // Currently news and views.
        ), $atts) );
    
        // For getting the Query variable on a statcci front page, you have
        // to use \'page\' and not \'paged\'. Weird.          
        $paged = ( get_query_var(\'paged\') ) ? get_query_var(\'paged\') : 1;
    
    
        // Two things needed: Not using the game library,
        // Definitely using the supplied slug.
        // These are two objects.
    
        $dontUse = get_category_by_slug(\'game-library\');
        $catUsed = get_category_by_slug($atts->categoryslug);
    
        // Args for the custom query
         $query_args = array(
           \'posts_per_page\'   => intval($foo),
           \'category__not_in\' => $dontUse->term_id,
           \'cat\' => $catUsed->term_id,
           \'paged\' => $paged
         );
    
        $custom_query = new WP_Query($query_args);                      
    
                $output = \'<div id="blogroll">\';  
                while ( $custom_query->have_posts() ) : $custom_query->the_post();
    
                    $output .= "<div class=\'home_post col span_12 clear-both\'>";
                    $output .=      "<div class=\'col span_3\'><a href=\'" . get_the_permalink() . "\'>" . get_the_post_thumbnail(get_the_ID(), \'home_post_thumb\') . "</a></div>";
                    $output .=      "<div class=\'col span_9 col_last right-edge\'>";
                    $output .=        "<h2 class=\'home_post_header\'>";
                    $output .=           \'<a href="\' . get_the_permalink() . \'">\' . get_the_title() . "</a>";
                    $output .=        "</h2>";
                    $output .=        get_the_excerpt();
                    $output .=      \'<a class="home-more-link" href="\' . get_the_permalink() . \'"><span class="continue-reading">Read More</span></a>\';
                    $output .=      "</div>";
                    $output .= "</div>";
    
                endwhile;
    
                wp_reset_postdata();
    
                // Pagination not working, but it outputs just fine?
                $output .= \'<div id="pagination" class="blogroll-pagination">\' . home_pagination($custom_query) . \'</div></div>\';
                wp_reset_query();              
    
                return $output;  
     }
    

    SO网友:Touqeer Shafi

    如果我需要分页,我会选择WP-PageNavi 插件。

    $paged = get_query_var(\'paged\') ? get_query_var(\'paged\') : 1;
    $args = array(\'post_type\' => \'post\', \'posts_per_page\' => 5, \'paged\' => $paged);
    $loop = new WP_Query( $args );
    while ( $loop->have_posts() ) : $loop->the_post();
    
        // Your Custom Loop Code Here
    
    endwhile; ?>
    
    <?php wp_pagenavi( array( \'query\' => $loop ) ); ?>
    
    WP PageNavi将根据您的查询呈现分页。

    结束

    相关推荐

    Custom pagination

    我使用模板部分来显示投资组合项目。它不是页面模板,只是公文包。php文件,我将其包含在get_template_part(\'portfolio\'); 至主页。现在一切都很好。但我想对这个部分使用分页。这是我的代码块;<?php global $wp_query; $paged = get_query_var(\'paged\') ? get_query_var(\'paged\') : 1; $port_args = array( \'post_t