it-roy-ru.com

Как отсортировать CPT по пользовательскому мета-значению (дате) и возвращать посты месяц за месяцем

Для дальнейшего использования:
Я использую замечательный Meta Box Plugin , чтобы ускорить создание мета-блоков для своих пользовательских типов записей.

Моя цель:
Для создания настраиваемого раздела событий, напоминающего традиционный календарь, такой как get_calendar, но для определенного пользовательского типа записи.

Проблема:
- Полагаясь исключительно на использование Wordpress, встроенных в параметры времени , я могу возвращать свои сообщения в порядке ASC, аналогичном традиционному календарю, но я ограничен отображением сообщений только текущий день, поскольку нет возможности запрашивать и возвращать запланированные сообщения - очевидно, это проблема, поскольку мне нужно отображать ВСЕ сообщения о событиях за текущий месяц и далее ...
- Кроме того, мне также нужно иметь возможность переходить на "предыдущие" и "предстоящие" месяцы, аналогичные get_calendar.

Мое решение до сих пор:
- Из-за ограничений параметров времени я решил вместо этого возвращать свои сообщения с помощью параметра WP_Querymeta_key и назначать его в поле "startdate" событий, а затем orderby - meta_value_num...

Похоже, это повторяет ту же функциональность, что и я, по большей части, но теперь у меня возникла серьезная проблема:

"Как мне трактовать это мета-значение точно так же, как параметры родного времени wordpress, чтобы я мог хранить эти данные соответствующим образом для каждого месяца и иметь возможность просматривать страницы в течение месяцев, похожих на архив get_calendar?"

Надеюсь, я был достаточно определенным в своем объяснении, чтобы помочь любому, кто читает это, понять все это. Если нет, пожалуйста, дайте мне знать, и я с радостью постараюсь уточнить, что это такое ... и спасибо за помощь!


Ниже вставлен мой текущий шаблон "Календарь/События", а также скриншот того, как он будет выглядеть наиболее вероятно на внешнем интерфейсе.

<?php
/*
Template Name: Calendar
*/
?>

<?php get_header(); ?>

<!-- featured_images.php -->
<?php include ('featured_images.php'); ?>

    <div id="full_col">

        <h2 class="feed_title_full"><?php wp_title('', true); ?></h2>
        <div id="calendar_nav">
            <h4 id="current_month"><?php the_time( 'F Y' ); ?></h4>
        </div>

        <ul id="calendar">

            <?php $current_year = date('Y'); // Get current YEAR ?> 
            <?php $current_month = date('m'); // Get current MONTH ?>
            <?php $calandar_posts = new WP_Query(
                array(
                    'post_type' => 'calendar', 
                    'year' => $current_year,
                    'monthnum' => $current_month, // Show ALL posts for current Month 
                    'meta_key' => 'epr_startdate',
                    'orderby' => 'meta_value_num',
                    'order' => 'ASC', 
                    'posts_per_page' => -1, 
                    'paged' => get_query_var('paged') ? get_query_var('paged') : 1,
                )); 
            ?>
            <?php if($calandar_posts->have_posts()) : while($calandar_posts->have_posts()) : $calandar_posts->the_post(); ?>

                <li class="calendar_entry">
                    <a href="<?php the_permalink(); ?>" class="calendar_link" title="<?php the_title_attribute(); ?>"></a>
                    <div class="entry_date">
                        <?php echo get_post_meta($post->ID, 'epr_startdate', TRUE); ?>
                    </div>
                    <div class="shadow_overlay"></div>
                    <?php the_post_thumbnail('calendar-teaser', array('class' => 'calendar-teaser-img', 'alt' => 'View Event')); ?>
                </li>

            <?php endwhile; else: ?>
                <h2>No Events for the month of <?php the_time( 'F' ); ?></h2>
            <?php endif; ?>
            <?php wp_reset_query(); ?>

        </ul>

    </div>

<?php get_footer(); ?>

enter image description here

2
Mr.Brown

Это не полный код копирования/вставки, но, надеюсь, он достаточно понятен, чтобы начать работу.

Первым шагом является регистрация вашего типа записи и добавление правила перезаписи для обработки лет/месяцев. Это даст вам отдельные события в event/post-name/, ваш архив типов записей в calendar и обработает входящие запросы для calendar/yyyy/mm/. Обязательно перейдите на страницу "Настройки"> "Постоянные ссылки" после того, как она будет добавлена, чтобы очистить правила перезаписи.

function wpa88173_calendar_post_type() {

    // just the important bits shown here
    $args = array(
        'rewrite' => array( 'slug' => 'event' )
        'has_archive' => 'calendar',
    );

    register_post_type( 'calendar', $args );

    add_rewrite_rule(
        '^calendar/([0-9]{4})/([0-9]{2})/?',
        'index.php?post_type=calendar&calendar_year=$matches[1]&calendar_month=$matches[2]',
        'top'
    );

}
add_action( 'init', 'wpa88173_calendar_post_type' );

Следующим шагом является добавление переменных запросов calendar_year и calendar_month, чтобы WordPress добавлял их в массив переменных запросов при разборе входящих запросов.

function wpa88173_calendar_query_vars( $query_vars ) {
    $query_vars[] = 'calendar_year';
    $query_vars[] = 'calendar_month';
    return $query_vars;
}
add_filter('query_vars', 'wpa88173_calendar_query_vars' );

Следующим шагом является добавление действия в pre_get_posts, который проверяет, является ли он архивом типа записей календаря, выбирает год/месяц или устанавливает его на текущий год/месяц, а затем изменяет запрос с параметрами meta_query для загрузки запрошенного года/месяца , Смотрите WP_Query для получения дополнительной информации о мета-запросах. Предполагается, что формат даты yyyymmdd.

function wpa88173_calendar_query( $query ) {
    // is it a post type archive?
    if( ! $query->is_post_type_archive( 'calendar' ) )
        return;

    // is it the main query and not an admin page?      
    if( $query->is_main_query()
        && ! is_admin() ) {

        // check if year/month was set via the URI, or set it to current year/month
        ( ! empty( $query->query_vars['calendar_year'] ) ) ? $query_year = $query->query_vars['calendar_year'] : $query_year = date('Y');
        ( ! empty( $query->query_vars['calendar_month'] ) ) ? $query_month = $query->query_vars['calendar_month'] : $query_month = date('m');

        // meta_query parameters for events between start and end dates
        $date_start = $query_year . $query_month . '01';
        $date_end = $query_year . $query_month . '31';
        $meta_query = array(
            array(
                'key' => 'event_date',
                'value' => array( $date_start, $date_end ),
                'compare' => 'BETWEEN',
                'type' => 'NUMERIC'
            )
        );

        // modify the query
        $query->set( 'meta_key', 'event_date' );
        $query->set( 'orderby', 'meta_value_num' );
        $query->set( 'order', 'ASC' );
        $query->set( 'meta_query', $meta_query );

    }

}
add_action( 'pre_get_posts', 'wpa88173_calendar_query' );

Последним шагом будет создание календаря в шаблоне и создание следующих/предыдущих ссылок на страницу в течение нескольких месяцев. Вы можете получить запрашиваемый год/месяц в шаблоне через get_query_var .

EDIT- Вот пример построения ссылок с простой старой математикой

( '' == get_query_var( 'calendar_month' ) ) ? $this_month = date( 'n' ) : $this_month = ltrim( get_query_var( 'calendar_month' ), '0' );
( '' == get_query_var( 'calendar_year' ) ) ? $this_year = date( 'Y' ) : $this_year = get_query_var( 'calendar_year' );

if( 1 == $this_month ):
    $next_month = 2;
    $prev_month = 12;
    $next_year = $this_year;
    $prev_year = $this_year - 1;
elseif( 12 == $this_month ):
    $next_month = 1;
    $prev_month = 11;
    $next_year = $this_year + 1;
    $prev_year = $this_year;
else:
    $next_month = $this_month + 1;
    $prev_month = $this_month - 1;
    $next_year = $this_year;
    $prev_year = $this_year;
endif;

$next_month = str_pad( $next_month , 2, '0', STR_PAD_LEFT );
$prev_month = str_pad( $prev_month , 2, '0', STR_PAD_LEFT );

echo 'next month: /calendar/' . $next_year . '/' . $next_month . '/';
echo 'previous month: /calendar/' . $prev_year . '/' . $prev_month . '/';
5
Milo