合并一个带有POST_REWIND的复杂查询并将帖子拆分为两列

时间:2016-07-12 作者:Gregory Schultz

我需要帮助query 使用rewind_posts 因此,如果某个帖子属于某个特定类别,它会移至顶部。我想做的是使用一个查询,将帖子拆分为两列页面(左div和右div),如果帖子属于名为First, 它位于左栏列表的顶部。

我可以做两个不同的queries 但我很难合并成一个query. 我很想自己做,但是$i++ 我很困惑,所以我想寻求帮助,了解如何将两个单独的查询合并为一个查询。

这是第一次query 如果任何职位属于第一类或第二类,则将其置于首位:

<?php $args = array(
\'tax_query\' => array(
array(
    \'taxonomy\' => \'post-status\',
    \'field\' => \'slug\',
    \'terms\' => array (\'post-status-published\')
    )
)
); $query = new WP_Query( $args ); ?>
<?php if ( $query->have_posts() ) : $duplicates = []; while ( $query->have_posts() ) : $query->the_post(); ?>

    <?php if ( in_category( \'First\' ) ) : ?>
        <?php the_title();?><br>
        <?php $duplicates[] = get_the_ID(); ?>

    <?php endif; endwhile; ?>
    <?php $query->rewind_posts(); ?>

<?php while ( $query->have_posts() ) : $query->the_post(); ?>
    <?php if ( in_category( \'Second\' ) ) : if ( in_array( get_the_ID(), $duplicates ) ) continue; ?>

        <?php the_title(); ?><br>
        <?php $duplicates[] = get_the_ID(); ?>

    <?php endif; endwhile; ?>

<?php $query->rewind_posts(); ?>          
<?php while ( $query->have_posts() ) : $query->the_post(); ?>

        <?php if ( in_array( get_the_ID(), $duplicates ) ) continue; ?>
        <?php the_title();?><br>

<?php endwhile; wp_reset_postdata(); endif; ?>
这是query 将帖子拆分为两列:

<?php $args = array(
\'tax_query\' => array(
array(
\'taxonomy\' => \'post-status\',
\'field\' => \'slug\',
\'terms\' => array (\'post-status-published\')
))); $wp_query = new WP_Query( $args ); ?>
<div class="left">
<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) == 0) : $wp_query->next_post(); else : the_post(); ?>

<?php the_title(); ?><br>

<?php endif; endwhile; ?></div><?php else:?>
<?php endif; ?>

<?php $i = 0; rewind_posts(); ?>
<div id="right">

<?php if (have_posts()) : while(have_posts()) : $i++; if(($i % 2) !== 0) : $wp_query->next_post(); else : the_post(); ?>

<?php the_title(); ?><br>

<?php endif; endwhile; ?></div><?php else:?>
<?php endif; ?>
我正在努力完成的一个例子:

Title - First      | Title
Title - Second     | Title
Title              | Title
谢谢!

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

它是完整的。这是我的最终代码:

// the query. Only show posts that belong to the taxonomy called "post-status" and they have a slug called "post-status-published"
<?php $args = array(\'tax_query\' => array(array(\'taxonomy\' => \'post-status\',\'field\' => \'slug\',\'terms\' => array (\'post-status-published\')))); $query = new WP_Query( $args );?>

// the loop. Also gets variables to false and enables the variable "duplicate".
<?php if ( $query->have_posts() ) : $firstonly = false; $major = false; $groupa = false; $groupb = false; $groupc = false; $groupd = false; $duplicates = []; while ( $query->have_posts() ) : $query->the_post(); ?>


// checks if any post in the loop belongs to a certain category. If any post with those category is in the loop, the variable is changed to "true". Also adds the "Post ID" in that category to the "duplicate" variable.
<?php if ( in_category(\'first\') ) : ?>
    <?php $firstonly = true; ?>
    <?php $duplicates[] = get_the_ID(); ?>
<?php endif; ?>
<?php if ( in_category(array(\'major\',\'major-first\') ) ) : ?>
    <?php $major = true; ?>
    <?php $duplicates[] = get_the_ID(); ?>
<?php endif; ?>
<?php if ( in_category(array(\'group-a-first\',\'group-a\')) ) : ?>
    <?php $groupa = true; ?>
    <?php $duplicates[] = get_the_ID(); ?>
<?php endif;?>
<?php if ( in_category(array(\'group-b-first\',\'group-b\')) ) : ?>
    <?php $groupb = true; ?>
    <?php $duplicates[] = get_the_ID(); ?>
<?php endif;?>
<?php if ( in_category(array(\'group-c-first\',\'group-c\')) ) : ?>
    <?php $groupc = true; ?>
    <?php $duplicates[] = get_the_ID(); ?>
<?php endif;?>
<?php if ( in_category(array(\'group-d-first\',\'group-d\')) ) : ?>
    <?php $groupd = true; ?>
    <?php $duplicates[] = get_the_ID(); ?>
<?php endif;?>


// Close the loop and rewind the query
<?php endwhile; endif; ?>
<?php $query->rewind_posts(); ?>


// The output of the loop. Only show the output if the above is set to true.
<?php if ($major == true):?>
    <div class="group-major">
    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'major-first\'):?>
                <div class="major-first">
                major first - <?php print $postData->post_title;?><br>
                </div>
            <?php endif;?>
    <?php } ?>
    <div class="group-sorted">
    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'major\'):?>
                <div class="post">
                major - <?php print $postData->post_title;?><br>
                </div>
            <?php endif;?>
    <?php } ?>
    </div></div>
<?php endif;?>
<?php if ($firstonly == true):?>
    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            first - <?php print $postData->post_title;?><br>
    <?php } ?>
<?php endif;?>
<?php if (($groupa == true) or ($groupb == true) or ($groupc == true) or ($groupd == true)):?>
    <?php if (($groupa == true) && ($groupb == false)):?>
        group solo start<br>
        <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-a-first\'):?>
                group a first (only) - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>

    <?php else:?>
        group multi start<br>
        <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-a-first\'):?>
                group a first (multi) - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>

    <?php endif;?>

    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-a\'):?>
                group a - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>

    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-b-first\'):?>
                group b first - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>
    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-b\'):?>
                group b - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>

    <?php if (( true == $groupa ) && (false == $groupb) && (false == $groupc) && (false == $groupd)) :?>
        solo end<br>
    <?php endif;?>
    <?php if (( true == $groupa ) && (true == $groupb) && (false == $groupc) && (false == $groupd)) :?>
        group b multi end<br>
    <?php endif;?>


    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-c-first\'):?>
                group c first - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>
    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-c\'):?>
                group c - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>

    <?php if (( true == $groupa ) && (true == $groupb) && (true == $groupc) && ($groupd == false)) :?>
        group c multi end<br>
    <?php endif;?>

    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-d-first\'):?>
                group d first - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>
    <?php foreach($duplicates as $postID) { ?>
        <?php $postData = get_post( $postID );?>
            <?php if(esc_html(get_the_category($postID)[0]->slug) == \'group-d\'):?>
                group d - <?php print $postData->post_title;?><br>
            <?php endif;?>
    <?php } ?>

    <?php if (( true == $groupa ) && (true == $groupb) && (true == $groupc) && ($groupd == true)) :?>
        group d multi end<br>
    <?php endif;?>

<?php endif;?>

//the second loop. Also sets two columns
<?php $row_start = 1; while ( $query->have_posts() ) : $query->the_post();?>

    // if the category "first" is set to true, split posts into columns with most posts favoring the left. I.E. if the loop has ten posts, it is evenly split. If not, the split favors the right side.
    <?php if(true == $firstonly):?>
        <?php if(in_array( get_the_ID(), $duplicates ) ) continue; ?>
            <?php if($row_start % 2 != 0 && $row_start != ($sum_total = $wp_query->found_posts - count($duplicates))):?>
                <?php $left[] = get_the_ID();?>
            <?php else:?>
                <?php $right[] = get_the_ID();?>
            <?php endif;?>
    <?php else:?>
        <?php if(in_array( get_the_ID(), $duplicates ) ) continue; ?>
            <?php if($row_start % 2 != 0):?>
                <?php $left[] = get_the_ID();?>
            <?php else:?>
                <?php $right[] = get_the_ID();?>
            <?php endif;?>
    <?php endif;?>

// end the column, the loop, the query and reset the query.     
<?php ++$row_start; endwhile; wp_reset_postdata();?>

// the output of the second loop.   
<?php foreach($left as $postID) { ;?>
    <?php $postData = get_post( $postID );?>
    left - <?php print $postData->post_title;?><br>
<?php } ?>
<?php foreach($right as $postID) { ;?>
    <?php $postData = get_post( $postID );?>
    right - <?php print $postData->post_title;?><br>
<?php } ?>
谢谢大家的帮助!这可能是我遇到的最复杂的问题。非常感谢您的帮助!

SO网友:Pieter Goosen

由于样式问题,这种方法变得有点像tameletjie,让我们对所有内容进行返工,看看不同的方法

我认为我们应该做的是$posts 阵列通过usort() 按照我们想要的顺序对帖子进行排序,然后我们可以正常运行循环

创建我们的查询:

<?php 
$args = array(
    \'tax_query\' => array(
        array(
            \'taxonomy\' => \'post-status\',
            \'field\' => \'slug\',
            \'terms\' => array (\'post-status-published\')
        )
    )
); 
$query = new WP_Query( $args ); 
现在我们已经运行了查询,我们需要获取$posts 属性来自$query 并对其进行排序。因此,这一部分将位于我们的查询下方:(NOTE: 这完全没有经过测试

if ( $query->have_posts() ) :
    // Now we will use usort to sort the posts array
    @usort( $query->posts, function ( $a, $b ) // @ hides the bug before PHP 7
    {
        // Assign sortable values for categories to sort posts by
        $array = [\'a\' => $a, \'b\' => $b];
        $sort_order_a = \'\';
        $sort_order_b = \'\';
        foreach ( $array as $key=>$p ) {
            if ( in_category( \'First\', $p ) ) {
                ${\'sort_order_\' . $key} = 1;
            } elseif ( in_category( \'Second\', $p ) ) { 
                ${\'sort_order_\' . $key} = 2;
            } else {
                ${\'sort_order_\' . $key} = 3;
            }
        }

        // Now that we have a custom sorting order, lets sort the posts
        if ( $sort_order_a !== $sort_order_b ) {
            // Make sure about <, change to > to change sort order
            return $sort_order_a < $sort_order_b; 
        } else { 
            /** 
             * Sort by date if sorting order is the same, 
             * again, to change sort order, change > to <
             */
            return $a->post_date > $b->post_date;
        }
    });

    // Our posts is now sorted, run the loop normally
    // Define our counter to set our columns
    $counter = 0;
    $midpoint = ceil( $query->post_count / 2 );

    while ( $query->have_posts() ) :
        $query->the_post();
            // set our left div on first post
            if ( 0 == $counter ) : 
                ?>
                <div id="left">
                <?php
            endif;

            // Close our left div and open the right one on midpoint
            if ( ( $counter + 1 ) == $midpoint ) :
                <?php
                </div>
                <div id="right">
                <?php
            endif;

            // Lets output the posts with different styling
            if ( in_category( \'First\', get_the_ID() ) {
                // Apply styling for category First and display title
                    the_title();
            } elseif ( in_category( \'First\', get_the_ID() ) {
                // Apply styling for category Second and display title
                    the_title();
            } else {
                // Apply styling for other posts and display title
                    the_title();
            }

            /**
             * Lets close the div and bail if we have only one post, 
             * or if we are on the last post
             */
            if (    1 == $post_count 
                 || ( $counter + 1 ) == $post_count
            ) :
                ?> 
                </div>
                <?php
            endif;

            // Update our counter
            $counter++;

    endwhile;
    wp_reset_postdata();
endif;
原始答案

您的第二段代码不起作用,超出了您之前问题的全部原因。请注意,您不应该使用$wp_query 作为局部变量,它是一个保留的全局变量,专门用于WordPress中保存主查询对象。打破这一全球格局将打破许多其他东西。你在做什么query_posts() 是的,这也是为什么您永远不应该使用查询帖子。

你的问题是你的计数器被错误地更新了,因此它错误地添加了你的div。我们需要做的是只在有条件的声明中更新我们的意见,以防止职位被重复计算,从而破坏布局。

我们将只使用第一个循环并相应地修改它。唯一棘手的部分是何时打开和关闭div

编辑

由于代码有点技术性,我放弃了我原来的想法。我们仍将使用第一块中的代码,除了像以前一样循环浏览帖子并创建一个新数组,最后循环浏览该数组并显示帖子会容易得多。

<?php 
$args = array(
    \'tax_query\' => array(
        array(
            \'taxonomy\' => \'post-status\',
            \'field\' => \'slug\',
            \'terms\' => array (\'post-status-published\')
        )
    )
); 
$query = new WP_Query( $args ); 

if ( $query->have_posts() ) :

    /**
     * Get the amount of posts in the loop, this will be used
     * to calculate when to open and close our divs
     */
    $post_count = $query->post_count;

    /**
     * Get a midpoint to break the div into left and right
     */
    $midpoint = ceil( $post_count / 2 );

    $duplicates  = []; 
    $post_titles = [];

    while ( $query->have_posts() ) : 
        $query->the_post(); 

        if ( in_category( \'First\' ) ) :
            $post_titles[] = apply_filters( \'the_title\', get_the_title() );
            $duplicates[] = get_the_ID(); 

        endif; 
    endwhile; 

    $query->rewind_posts();

    while ( $query->have_posts() ) : 
        $query->the_post(); 

        if ( in_category( \'Second\' ) ) : 
            if ( in_array( get_the_ID(), $duplicates ) ) 
                continue;

            $post_titles[] = apply_filters( \'the_title\', get_the_title() );
            $duplicates[] = get_the_ID();

        endif; 
    endwhile;

    $query->rewind_posts();          

    while ( $query->have_posts() ) : 
        $query->the_post();

        if ( in_array( get_the_ID(), $duplicates ) ) 
            continue; 

        $post_titles[] = apply_filters( \'the_title\', get_the_title() );

    endwhile; 
    wp_reset_postdata(); 

    // Now that we have an array of post titles sorted, lets display them
    foreach ( $post_titles as $key=>$post_title ) :
        // Open our left div
        if ( 0 == $key ) : 
            ?>
            <div id="left">
            <?php
        endif;

        // Close our left div and open the right one on midpoint
        if ( ( $key + 1 ) == $midpoint ) :
            <?php
            </div>
            <div id="right">
            <?php
        endif;

        // Display the post title
        echo $post_title . \'</br>\';

        /**
         * Lets close the div and bail if we have only one post, 
         * or if we are on the last post
         */
        if (    1 == $post_count 
             || ( $key + 1 ) == $post_count
        ) :
            ?> 
            </div>
            <?php
            break;
        endif;

    endforeach;

endif; 
?>
重要注意事项:Al代码未经测试,可以根据需要进行改进。由于未经测试,可能会有轻微的语法错误或小错误

相关推荐

WordPress Custom Post Loop

我正在尝试循环浏览自定义WordPress帖子,遇到了一个问题,比如我添加了自定义字段并想在中显示它<li> 使用循环。我成功地完成了操作,但数据/链接/类别正在重复,如果类别与以下内容相同,我希望只显示一次:如果我有2篇带有data1类别的帖子,那么链接将只显示data1once 但我有2个不同类别的帖子,然后它会分别显示每个帖子。Sample Code:<ul class="filter filter-top"> <li cla