两个自定义循环、分页、偏移量

时间:2016-02-14 作者:Colton

我有两个使用WP\\u查询的循环。

第一个循环显示X个帖子。无分页
(loop A)

第二个循环显示Y柱。使用自定义分页
(loop B)

这有点管用;但是您可以看到第二个循环重复第一个循环中的X个帖子。首先想到的是设置一个偏移量(等于X),但它会破坏分页,而且Codex上有一整页专门讨论这个问题。它还有一个变通方法,但问题是我有两个循环,所以这个变通方法适用于这两个循环。

So the question is
我如何使这项工作按预期进行<一个可能的解决方案是使Codex中的代码成为第二个循环的“目标”,但我不是程序员,我不知道如何做到这一点。也许有更好的方法来实现我的目标,但我想不出任何其他的选择。

其他信息1)我不能只使用一个循环,因为我的标记有多么复杂
2)所有代码都是在网上找到的
3)两个循环都不受作者、类别或其他限制。它始终是相同的内容,两个不同的布局“组合”成一个“提要”。

and since I can\'t post more than 2 links, here is the pagination code

function custom_pagination($numpages = \'\', $pagerange = \'\', $paged=\'\') {
    if (empty($pagerange)) {
        $pagerange = 2;
    }

/**
    This first part of our function is a fallback
    for custom pagination inside a regular loop that
    uses the global $paged and global $wp_query variables.

    It\'s good because we can now override default pagination
    in our theme, and use this function in default quries
    and custom queries.
**/

global $paged;
if (empty($paged)) {
    $paged = 1;
}
if ($numpages == \'\') {
    global $wp_query;
    $numpages = $wp_query->max_num_pages;
    if(!$numpages) {
        $numpages = 1;
    }
}

/** 
    We construct the pagination arguments to enter into our paginate_links
    function. 
**/

$pagination_args = array(
    \'base\'            => get_pagenum_link(1) . \'%_%\',
    \'format\'          => \'page/%#%\',
    \'total\'           => $numpages,
    \'current\'         => $paged,
    \'show_all\'        => False,
    \'end_size\'        => 1,
    \'mid_size\'        => $pagerange,
    \'prev_next\'       => True,
    \'prev_text\'       => __(\'&laquo;\'),
    \'next_text\'       => __(\'&raquo;\'),
    \'type\'            => \'plain\',
    \'add_args\'        => false,
    \'add_fragment\'    => \'\'
);

$paginate_links = paginate_links($pagination_args);

if ($paginate_links) {
    echo "<nav class=\'custom-pagination\'>";
        echo "<span class=\'page-numbers page-num\'>Page " . $paged . " of " . $numpages . "</span> ";
        echo $paginate_links;
    echo "</nav>";
}
}

solution from Codex

add_action(\'pre_get_posts\', \'myprefix_query_offset\', 1 );
function myprefix_query_offset(&$query) {

//Before anything else, make sure this is the right query...
if ( ! $query->is_home() ) {
    return;
}

//First, define your desired offset...
$offset = 1;

//Next, determine how many posts per page you want (we\'ll use WordPress\'s settings)
$ppp = get_option(\'posts_per_page\');

//Next, detect and handle pagination...
if ( $query->is_paged ) {

    //Manually determine page query offset (offset + current page (minus one) x posts per page)
    $page_offset = $offset + ( ($query->query_vars[\'paged\']-1) * $ppp );

    //Apply adjust page offset
    $query->set(\'offset\', $page_offset );

}
else {

    //This is the first page. Just use the offset...
    $query->set(\'offset\',$offset);

}
}


add_filter(\'found_posts\', \'myprefix_adjust_offset_pagination\', 1, 2 );
function myprefix_adjust_offset_pagination($found_posts, $query) {

//Define our offset again...
$offset = 1;

//Ensure we\'re modifying the right query object...
if ( $query->is_home() ) {
    //Reduce WordPress\'s found_posts count by the offset... 
    return $found_posts - $offset;
}
return $found_posts;
}

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

我不能只使用一个循环,因为我的标记有多么复杂

无论多么复杂,在决定运行多个循环时,标记永远不应该是有效的基础。只有在绝对没有其他方法来实现某个结果的情况下才应该使用多个循环,而且几乎总是在每个查询参数需要不同结果的情况下使用,例如每个帖子类型每个页面需要不同的帖子。

这两个循环都不受作者、类别或其他限制

上述语句也不验证第二个循环的使用。仅基于此语句,无论标记有多复杂,我们都只需要一个循环

特定查询结果的显示方式始终可以通过以下方式进行操作

  • rewind_posts() 它允许您根据需要第二次、第三次或第一百次重新运行循环

    自定义计数器或内置循环计数器,用于统计帖子,如果循环计数器/自定义计数器命中特定数字,则可以执行不同的操作

    有条件的标签/语句,可根据特定条件(例如帖子类型或类别)针对特定帖子

    过滤器,如the_posts 它允许您更改返回帖子的数组,其中包括添加/删除和/或重新排列帖子

    正常的PHP函数,如usort() 可用于在将返回的帖子数组输出到屏幕之前对其进行排序

    我们总是可以使用pre_get_posts 显示我们想要的

    这些只是几个选项,您可以使用它们来代替运行多个循环。多个循环的问题是

    在分页时,它们是有问题的

    导致不必要的数据库查询,从而减慢页面加载时间并浪费资源

您应该始终记住的一件重要事情是,绝不能将显示主查询结果的主循环替换为自定义查询。他们总是导致比解决问题更多的问题。你应该慢慢来,阅读以下帖子:

要解决您的问题,您可以删除pre_get_posts 行动和found_posts 过滤,因为您不需要设置任何偏移或重新计算分页。

您需要根据需要调整所需页面上的循环

示例1

将第一篇帖子的样式设置为不同的,并显示比其他帖子更多的信息

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();

            if ( 0 === $wp_query->current_post ) { // Target the first post only
                // Do what you need to do for the first post only
            } else {
                // Display all the other posts as needed   
            }
    }
}

OR

if ( have_posts() ) {
    // Start our custom counter
    $counter = 0;
    while ( have_posts() ) {
        the_post();

            if ( 0 === $counter ) { // Target the first post only
                // Do what you need to do for the first post only
            } else {
                // Display all the other posts as needed   
            }
        // Update the counter 
       $counter++;
    }
}
您可以将此方法应用于任何复杂的标记。您可以设置自定义计数器以打开和关闭自定义div,将不同的样式应用于post位置,甚至创建post栅格。我已经在这方面发表了不少帖子,所以一定要搜索我的答案

示例2如果需要显示按帖子类型分组的帖子和帖子类型postpage. 在这里,我们将运行循环以显示来自post post type,倒带循环并重新运行,但这次仅显示page 岗位类型岗位

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();

            if ( \'post\' === get_post_type() ) { // Only display posts from post post type
                // Do what you need to do post post type posts
            } 
    }

    rewind_posts(); // Rewind the loop so we can run it again

    while ( have_posts() ) {
        the_post();

            if ( \'page\' === get_post_type() ) { // Only display posts from page post type
                // Do what you need to do page post type posts
            } 
    }
}
结论正如您所见,无论您觉得自己的标记有多复杂,它始终无法验证是否需要多个循环,一个循环就足够了,我们只需要巧妙地使用循环、PHP和过滤器就可以了

相关推荐

Duplicated <a> tag in loop

我坚持这个问题,看起来很简单,但找不到解决它的方法。我有这样的循环:<div class="features-items__wrapper"> <h2><?php echo $currentTitle; ?></h2> <?php global $post; $post_sl