Foreach循环按类别分组

时间:2015-06-23 14:43:10

标签: php wordpress

我在WordPress Stack Exchange上问了这个问题,并且24小时后没有收到太多回复。所以我想我会把它带到一个更大的社区。

无论如何,我正在创建一个活动插件,但是我在确定列表页面时遇到了一些麻烦。它显示了所有事件,但是我希望它按月分组。该声明需要提取事件的日期,抓住月份,并将特定月份的记录组合在一起。我知道这将是一个foreach,但我不知道如何写它。

这是我的循环:

 // Query Post Type
$args = array(
    'post_type' => 'events',
    'post_status' => 'publish',
    'meta_key' => '_eDate',
    'orderby' => 'meta_value_num'
);
$the_query = new WP_Query($args);

// Build It
if ($the_query->have_posts()) :
    ?>
    <div id="event-list">
        <?php
        global $post;

        $month_array = array();
        while ($the_query->have_posts()) : $the_query->the_post();

            var_dump( get_post_meta( $post->ID, '_eDate', true ) ); 

            $date_field = get_post_meta( $post->ID, '_eDate', true );
            $month_format = new DateTime();
            $month_format->createFromFormat('Y-m-d', $date_field); 
            $month_number = $month_format->format('m'); 
            $month_array[] = $month_number; 

            if ($the_query != 0 && $month_number != $month_array[$the_query->current_post - 1]) //LINE 38
                echo '<h2>' . $month_format->format( 'F' ) . '</h2>'; 
            ?>

            <div class="row">
                <div class="event-image">
                    <a href="<?php echo get_permalink(get_the_ID()); ?>">
                        <?php
                        if (has_post_thumbnail()) {
                            the_post_thumbnail('thumbnail');
                        }
                        ?>
                    </a>
                </div>
                <div class="event-content">
                    <h3><a href="<?php echo get_permalink(get_the_ID()); ?>"><?php the_title(); ?></a></h3>
                    <div class="event-date"><?php display_event_date(); ?></div>
                    <div class="event-time"><?php display_event_time(); ?></div>
                    <div class="event-price"><?php display_event_price(); ?></div>
                    <br/>
                    <a href="<?php echo get_permalink(get_the_ID()); ?>" class="event-info">More Information</a>
                </div>
                <div class="event-buy">
                    <?php display_event_buy_online_url(); ?>
                </div>
            </div>
        </div>
        <?php wp_reset_postdata(); ?>
        <?php
    endwhile;
endif;

--- 编辑1 ---

我已根据输入更新了我的代码块。

var_dump正在输出string(10) "2015-07-09"

我也遇到两个错误。

  

注意:在第38行的C:\ xampp \ apps \ wordpress \ htdocs \ wp-content \ plugins \ wp-events-em4b \ views \ shortcode.php中无法将类WP_Query的对象转换为int

     

注意:未定义的偏移量:在第38行的C:\ xampp \ apps \ wordpress \ htdocs \ wp-content \ plugins \ wp-events-em4b \ views \ shortcode.php中< -

从int转换为文本的月份是错误的,它会在上次编辑帖子时拉动,但var_dump的日期正确。

2 个答案:

答案 0 :(得分:2)

正如我在回答您关于WPSE的问题时所述,您需要根据自定义字段中的日期对帖子进行排序。这就像向查询参数中添加正确的参数一样简单

如果您的日期保存为以下格式Y-m-d,则非常简单。你的年份将保持不变,所以你可以在技术上按月分类。

您只需要为orderorderby参数添加正确的值即可。您可以尝试以下

// Query Post Type
$args = array(
    'post_type' => 'events',
    'post_status' => 'publish',
    'meta_key' => '_eDate',
    'orderby' => 'meta_value'
);

如果您需要按月分类而不管年份,那么在执行循环之前,您需要使用usort()对循环进行排序。如果是这种情况,请告诉我,以便我可以相应地调整我的答案。

您已经声明自定义字段中的日期格式为Y-m-d,因此您的循环应根据自定义字段_eDate中的日期按日期正确排序

现在您需要做的就是检查循环中当前帖子与循环中上一个帖子之间的日期(月份),如果它们不同,则输出月份。您需要foreach循环,您既不需要输出缓冲,也不需要创建包含原始帖子数组帖子的新数组

以下代码未经测试,同时确保自定义字段中的日期格式正确无误。在循环内部,您需要先var_dump( get_post_meta( $post->ID, '_eDate', true ) );验证您是否以正确的格式获得了正确的值。我的代码中的所有内容都依赖于这一小段信息。如果_eDate自定义字段中的值或格式不正确,我的代码将失败。请根据需要调整,修改和滥用我的代码

 // Query Post Type
$args = array(
    'post_type' => 'events',
    'post_status' => 'publish',
    'meta_key' => '_eDate',
    'orderby' => 'meta_value' //HAD A BUG HERE, DID NOT SORT CORRECTLY, NEEDS TO BE meta_value
);
$the_query = new WP_Query($args);

// Build It
if ( $the_query->have_posts() ) :
    ?>
    <div id="event-list">
        <?php
        $month_array = array();
        while ( $the_query->have_posts() ) : 
            $the_query->the_post();

            $date_field = get_post_meta( $post->ID, '_eDate', true );
            $month_format = DateTime::createFromFormat( 'Y-m-d', $date_field ); // HAD A BUG HERE, CONVERTED WRONG DATE
            $month_number = $month_format->format('m');
            $month_array[] = $month_number; 

            // Choose the format you want to display as indicated below
            if ( $the_query->current_post == 0 ) // Output date id this is the first post
                echo '<h2>' . $month_format->format( 'F' ) . '</h2>'; // Output month name as January

            if (    $the_query->current_post != 0 //HAD A BUG HERE, WAS $the_query != 0
                 && $month_number != $month_array[$the_query->current_post - 1] 
            )
                echo '<h2>' . $month_format->format( 'F' ) . '</h2>'; // Output month name as January            
            ?>

            <div class="row">
                <div class="event-image">
                    <a href="<?php echo get_permalink(get_the_ID()); ?>">
                        <?php
                        if (has_post_thumbnail()) {
                            the_post_thumbnail('thumbnail');
                        }
                        ?>
                    </a>
                </div>
                <div class="event-content">
                    <h3><a href="<?php echo get_permalink(get_the_ID()); ?>"><?php the_title(); ?></a></h3>
                    <div class="event-date"><?php display_event_date(); ?></div>
                    <div class="event-time"><?php display_event_time(); ?></div>
                    <div class="event-price"><?php display_event_price(); ?></div>
                    <br/>
                    <a href="<?php echo get_permalink(get_the_ID()); ?>" class="event-info">More Information</a>
                </div>
                <div class="event-buy">
                    <?php display_event_buy_online_url(); ?>
                </div>
            </div>
        </div>
        <?php wp_reset_postdata(); ?>
        <?php
    endwhile;
endif;

修改

我修复了上面的代码并对其进行了测试。现在一切都按预期工作了。请参阅代码中有关已修复错误的注释

答案 1 :(得分:0)

这是一种可行的方法。此示例捕获将post事件呈现为变量的输出,将其存储在按月键入的数组中,然后遍历数组,以便您可以打印按月分组的事件。

虽然我不知道你的功能细节,但你需要对它捕捉月份的位置做一些调整。

<?php
// Query Post Type
$args = array(
    'post_type' => 'events',
    'post_status' => 'publish'
);

$the_query = new WP_Query($args);
$posts = array(); // array for storing posts by month

// Build It
if ($the_query->have_posts()) :
    ?>
    ob_start(); // start buffering the output from the posts
    <div id="event-list">
        <?php
        while ($the_query->have_posts()) : $the_query->the_post();
            ?>
            <div class="row">
                <div class="event-image alignleft">
                    <a href="<?php echo get_permalink(get_the_ID()); ?>">
                        <?php
                        if (has_post_thumbnail()) {
                            the_post_thumbnail('thumbnail');
                        }
                        ?>
                    </a>
                </div>
                <div class="event-content alignleft">
                    <h3><a href="<?php echo get_permalink(get_the_ID()); ?>"><?php the_title(); ?></a></h3>
                    <div class="event-date"><?php display_event_date(); ?></div>
                    <div class="event-time"><?php display_event_time(); ?></div>
                    <div class="event-price"><?php display_event_price(); ?></div>
                    <br/>
                    <a href="<?php echo get_permalink(get_the_ID()); ?>">More Information</a>
                </div>
                <div class="event-buy alignleft">

                    <div class="event-buy">
                        <a class="buy-btn btn" href="<?php display_event_buy_online_url(); ?>" target="_blank">Buy Online</a>
                    </div>
                </div>
            </div>
            <hr>
        </div>
        $post = ob_get_contents(); // get the contents of the post to a variable
        ob_end_clean(); // clear output buffer
        $month = date('m', strtotime(get_event_date())); // get event month *THIS NEEDS TO BE CHANGED*
        $posts[$month][] = $post; // append post to month array
        <?php wp_reset_postdata(); ?>
        <?php
    endwhile;

    sort($posts); // sort post array by month numbers

    foreach($posts as $month) {
        // starting to display posts for a new month
        foreach($month as $post) {
            echo $post; // output the saved post from variable
        }
    }
endif;

或者,您可以使用排序选项按日期对事件进行排序:

$args = (
    'orderby' => 'event_date',
    'order' =>   'ASC',`
);

然后检查post循环中的日期,如果要在月份更改时输出任何html,请检查循环中的帖子月份是否有更改。