programing

WordPress: WP_Query를 사용자 지정 날짜 필드별로 주문하고 매달 이후에 루프를 분할합니다.

stoneblock 2023. 9. 16. 08:30

WordPress: WP_Query를 사용자 지정 날짜 필드별로 주문하고 매달 이후에 루프를 분할합니다.

WordPress Custom Post Type을 사용하여 이벤트를 관리하고 사이트에 표시하고 있습니다.이벤트를 정렬하려면 날짜가 포함된 사용자 지정 메타 필드(예: YYY-MM-DD)를 사용합니다.메타 필드를 현재 날짜와 대조하여 확인합니다.다음과 같은 경우:

$current_date_query = date ('Y-m-d');

$temp = $wp_query; $wp_query= null; $wp_query = new WP_Query();

$wp_query->query(
    array(
       'post_type' => 'event',
       'meta_key' => 'event_date',
       'meta_compare' => '>=',
       'meta_value' => $current_date_query,
       'post_status' => 'publish',
       'posts_per_page' => '99',
       'orderby' => 'meta_value',
       'order' => 'ASC',
       'paged' => $paged
    )
); ?>


... Loop stuff ...

<?php endif; $wp_query = null; $wp_query = $temp; wp_reset_query(); ?>

저는 이제 매달 새로운 달 전에 헤드라인을 추가하고 싶습니다.다음과 같은 경우:

2018년1월

  • 이벤트 1
  • 이벤트2
  • 이벤트3

2018년2월

  • 이벤트4
  • 이벤트5

2018년3월

  • 이벤트5

등등...

매달 이후에 루프를 분할할 수 있는 방법은 없습니까?메타 필드에서 한 달을 써야 하는 것 같은데 방법을 모르겠어요.

(@FluffyKitten의 코멘트 덕분에) 다음과 같은 해결책을 시도했습니다.

<?php

/* declare an array to save the data */
$quarters = array();

foreach($posts as $q) {

    $donor_date = get_post_meta($q->ID,'gid_22',true);
    $donor_month = date('m',strtotime($donor_date));

    /* format the date once - best practice is not to repeat code */
    $formatteddate = date('d/m/Y',strtotime($donor_date));

    /* organise the dates by quarter, using the heading as the key for easy display */
    if(in_array($donor_month, array('01')))
       $quarters["January"][] = $formatteddate;

    else if(in_array($donor_month, array('02')))
       $quarters["February"][] = $formatteddate;

    else if(in_array($donor_month, array('03')))
       $quarters["March"][] = $formatteddate;

    else if(in_array($donor_month, array('04')))
       $quarters["April"][] = $formatteddate;

    else if(in_array($donor_month, array('05')))
       $quarters["May"][] = $formatteddate;

    else if(in_array($donor_month, array('06')))
       $quarters["June"][] = $formatteddate;

    else if(in_array($donor_month, array('07')))
       $quarters["July"][] = $formatteddate;

    else if(in_array($donor_month, array('08')))
       $quarters["August"][] = $formatteddate;

    else if(in_array($donor_month, array('09')))
       $quarters["September"][] = $formatteddate;

    else if(in_array($donor_month, array('10')))
       $quarters["Ocotber"][] = $formatteddate;

    else if(in_array($donor_month, array('11')))
       $quarters["November"][] = $formatteddate;

    else if(in_array($donor_month, array('12')))
       $quarters["December"][] = $formatteddate;
}

 /* now go through your array and display the results */
 foreach ($quarters as $quartername => $quarter){
     /* $quarters won't have any entry for quarters with no dates, so technically this 'if' isn't needed,
       however I've added it in case it will be needed it for any other changes you make */
     if ($quarter){ ?>

         <h3><?php echo $quartername; ?></h3>
         <table>
         <?php  foreach ($quarter as $qdate ){ ?>
             <tr><td> <?php echo $qdate; ?> </td></tr>
         <?php  }  // end foreach($quarter...) ?>
         </table>
     <?php
     } // end if
} // end foreach($quarters...)
?>

이제 결과는 다음과 같습니다.

오코트버

  • 02/10/2018
  • 29/10/2017

1월

  • 02/01/2018

디셈버

  • 02/12/2017
  • 01/12/2017

그럴지도 모른다

  • 02/05/2018

...

주문은 사용자 정의 필드가 아닌 게시 날짜를 기준으로 합니다.또한 연도별로 차이가 없습니다.2017년은 2018년과 마찬가지로 자체 루프가 있어야 합니다.

루프의 첫 번째 배열에 자신의 배열을 넣으려고 하면 효과가 없고 앞단에만 텍스트로 표시됩니다.

편집: 다음과 같은 사용자 지정 쿼리를 사용하여 월을 주문할 수 있습니다.

$posts = query_posts( array(
    'post_type' => 'event',
    'meta_key' => 'event_date',
    'meta_compare' => '>=',
    'meta_value' => $current_date_query,
    'post_status' => 'publish',
    'posts_per_page' => '99',
    'orderby' => 'meta_value',
    'order' => 'ASC',
    'paged' => $paged
) );

지금 문제는 오직 한 해뿐입니다.한 달에 한 해가 다른 모든 것을 월별로 분류합니다.

@FluffyKitten에서 시도한 솔루션이 제대로 작동하지 않습니다. 같은 달과 같은 해가 아닌 같은 달의 그룹으로 그룹화되어 다른 해의 같은 달에 게시물이 있을 때 오류가 발생합니다.

@ChinLeung이 제안한 대로 현재 월을 변수에 저장하여 언제 변경되었는지 테스트하고 헤더를 출력해야 합니다.예를 들어 이를 구현하려면 다음을 수행해야 합니다.

// Set current month
$current_month = '';

// Get event posts in order
$events = query_posts( array(
    'post_type' => 'event',
    'meta_key' => 'event_date',
    'meta_compare' => '>=',
    'meta_value' => date ('Y-m-d'),
    'meta_type'  => 'DATE',
    'post_status' => 'publish',
    'posts_per_page' => '99',
    'orderby' => 'meta_value',
    'order' => 'ASC',
    'paged' => $paged
) );

// Iterate over events
foreach($events as $key => $event){

  // Get event date from post meta
  $event_date = get_post_meta($event->ID, 'event_date', $single = true);

  // Cache event month/year
  $event_month = date('F Y', strtotime($event_date));

  // Open new group if new month
  if($current_month != $event_month){
    if($key !== 0) echo '</ul>';  
    echo "<h2>{$event_month}</h2>";
    echo '<ul>';  
  }     

  // Add event date as new list item
  echo "<li>{$event_date}</li>";

  // Cache $curret_month
  $current_month = $event_month;        
}

// Close the last list if query had events
if(count($events)) echo '</ul>';

편집

이 솔루션을 포스트 유형 아카이브에서 작동하도록 업데이트하려면 위의 내용 대신 테마의 functions.php 또는 이에 포함된 파일에 다음을 추가합니다.

/**
 * Get event date 
 *
 * @return string
 */
function get_event_date() {

    /** @global WP_Post $post */
    global $post;

    /** Get event date from post meta */
    return get_post_meta($post->ID, 'event_date', $single = true);
}

/**
 * Get event month/year formatted
 *
 * @param string $event_date
 * 
 * @return string
 */
function format_event_date($event_date) {
    return date('F Y', strtotime($event_date));
}

/**
 * Order events archive by event date post meta
 *
 * @param WP_Query $query
 *
 * @return WP_Query
 */
function events_archive_pre_get_posts($query) {
    if (!$query->is_main_query() || !is_post_type_archive('event')) return $query;
    $query->set('meta_key', 'event_date');
    $query->set('meta_compare', '>=');
    $query->set('meta_value', date('Y-m-d'));
    $query->set('meta_type', 'DATE');
    $query->set('posts_per_page', 2);
    $query->set('orderby', 'meta_value');
    $query->set('order', 'ASC');
    return $query;
}

add_filter('pre_get_posts', 'events_archive_pre_get_posts');

그러면 페이지당 게시물을 원하는 개수로 설정하면 페이지가 정상적으로 작동합니다.다음은 깔끔하게 포맷된 HTML 목록 사이에 날짜 헤더를 추가하는 데 사용할 수 있는 포스트 유형 보관 템플릿의 샘플입니다. 또는 적어도 SO가 탭을 공백으로 변환하기 전까지는:

<?php // Template header
get_header(); ?>


<?php /** @global WP_Query */
global $wp_query; ?>

<?php // Events archive loop
for($previous_month = ''; have_posts(); $previous_month = $formatted_date): the_post();

    // Get event date from post meta
    $event_date = get_event_date();

    // Format event month/year
    $formatted_date = format_event_date($event_date);

    // The formatted date is the first or not the same as previous event
    if($previous_month != $formatted_date):

        // Close previous list if this is not the first
        if($wp_query->current_post !== 0) echo "\n\t</ul>\n"; 

        // New month template ?>
    <h2><?php echo $formatted_date; ?></h2>
<?php
        // Open new list
        echo "\t<ul>\n";
    endif; 

    // Event post template ?>
        <li><?php echo $event_date; ?></li>
<?php endfor;

// Reset query 
wp_reset_query();

// Close the last list if query had events 
if(have_posts()) echo "\t</ul>\n"; ?>


<?php // Pagination
the_posts_pagination(); ?>


<?php // Template footer
get_footer();

현재 순환월을 변수에 저장하고 같은 달에 계속 순환하는지 확인할 수 있습니다.

하다를 $events는스e로할든의다의다fne할ssfu의 로 표시할 모든 의 배열입니다.WP_Post.

$current = 0;

foreach($events as $event){

    $eventDate = get_field('event_date', $event->ID);
    $month = date('m', strtotime($eventDate));

    // New month
    if($current != $month){
        $current = $month;
        // Perform actions of new month
    }

    // Perform normal actions for the event

}

언급URL : https://stackoverflow.com/questions/46494231/wordpress-order-wp-query-by-custom-date-field-and-split-the-loop-after-every-mo