Выводим будущие записи в WordPress

Если вы пишете в блог регулярно, то у вас, должно быть, не раз складывалась ситуация, что пост уже написан, а публиковать его вы ещё не хотите. Для этого в WordPress есть future post. Так почему бы пользователю не знать, что скоро выйдет такая-то статья?

Поэтому давайте будем выводить название будущих постов в любом нужном вам месте. Код функции, которую мы вставляем в файл functions.php вашей темы:

/**
 * Получение списка будущих постов
 */
function render_future_posts($args = [])
{
    $defaults = [
        'wrapper_tag' => 'ul',
        'item_tag'    => 'li',
        'title_tag'   => 'h3',
        'count'       => 10,
        'class'       => 'future-posts',
        'date_format' => 'd.m.Y H:i',
        'show_date'   => true,
    ];
    $args = wp_parse_args($args, $defaults);

    // Разрешенный список тегов
    $allowed_tags = [
        'ul', 'ol', 'div', 'section',
        'li', 'article',
        'h1', 'h2', 'h3', 'h4', 'h5', 'p', 'span'
    ];
    foreach (['wrapper_tag', 'item_tag', 'title_tag'] as $key) {
        if (!in_array($args[$key], $allowed_tags, true)) {
            $args[$key] = $defaults[$key];
        }
    }

    $count = max(1, (int) $args['count']);
    $query = new WP_Query([
        'post_type'      => 'post',
        'post_status'    => 'future',
        'posts_per_page' => $count,
        'orderby'        => 'date',
        'order'          => 'ASC',
        'no_found_rows'  => true,
    ]);

    if (!$query->have_posts()) {
        return '<p>Нет запланированных записей</p>';
    }

    $html = '';
    $html .= '<' . esc_html($args['wrapper_tag']) .
        ' class="' . esc_attr($args['class']) . '">';
    while ($query->have_posts()) {
        $query->the_post();
        $html .= '<' . esc_html($args['item_tag']) . '>';
        $html .= '<' . esc_html($args['title_tag']) . '>';
        $html .= esc_html(get_the_title());
        $html .= '</' . esc_html($args['title_tag']) . '>';
        if (!empty($args['show_date'])) {
            $html .= '<div class="future-date">';
            $html .= esc_html(get_the_date($args['date_format']));
            $html .= '</div>';
        }
        $html .= '</' . esc_html($args['item_tag']) . '>';
    }
    $html .= '</' . esc_html($args['wrapper_tag']) . '>';

    wp_reset_postdata();

    return $html;
}

/**
 * Shortcode: [future_posts wrapper="div" item="article" title="h2" count="5" class="future-cards" date_format="d.m.Y" show_date="1"]
 */
add_shortcode('future_posts', function ($atts) {
    $atts = shortcode_atts([
        'wrapper'     => 'ul',
        'item'        => 'li',
        'title'       => 'h3',
        'count'       => 10,
        'class'       => 'future-posts',
        'date_format' => 'd.m.Y H:i',
        'show_date'   => '1',
    ], $atts, 'future_posts');

    // нормализация булевых значений
    $show_date = !in_array(strtolower((string) $atts['show_date']), ['0', 'false', 'no', 'off', ''], true);

    return render_future_posts([
        'wrapper_tag' => (string) $atts['wrapper'],
        'item_tag'    => (string) $atts['item'],
        'title_tag'   => (string) $atts['title'],
        'count'       => (int) $atts['count'],
        'class'       => (string) $atts['class'],
        'date_format' => (string) $atts['date_format'],
        'show_date'   => $show_date,
    ]);
});

В любом месте вашей темы вы можете написать:

if(function_exists('render_future_posts')) echo render_future_posts();

Шорткод вывода будущих записей [future_posts]

Для тех, кто не хочет, чтобы посты выводились списком, укажите в параметрах функции любые другие парные теги, например:

if(function_exists('render_future_posts')) echo render_future_posts(['wrapper_tag' => 'div', 'item_tag' => 'article', 'title_tag' => 'h2', 'count' => 5]);

Если мы хотим выводить записи внутри статей, виджетов и т. п. — используем шорткод:

[future_posts count="5"]

Все настройки шорткода:

[future_posts wrapper="div" item="article" title="h2" class="future-cards" count="6" date_format="d.m" show_date="1"]

Нужна доработка WordPress?

Сделаю новую тему, плагин или разберусь с тем, что уже работает не так. Отвечаю в течение дня.

Обсудить проект

Ещё в блоге