Przy tworzeniu stron internetowych zdarza się, że musimy rozszerzać je o kalendarz wydarzeń. Dotyczy to różnego typu szkoleń, spotkań itp. W jednym z projektów stanąłem przed nie lada dylematem. Czy użyć jakiejś gotowej wtyczki czy poszukać rozwiązań w kodzie?

Jak na humanistę przystało (tak jestem humanistą, skończyłem Historię na Uniwersytecie Marii Curie-Skłodowskiej w Lublinie i im jestem starszy, jestem z tego dumny), wybrałem drugą, trudniejszą ścieżkę. Oczywiście najpierw przetestowałem wtyczki, szczególnie The Events Calendar, jednakże nie spowodowały one we mnie głębokiego poruszenia. Chociaż rozwiązanie, które zastosowałem ma również mankamenty.

Jako, że był to wydzielony typ posta, uznałem za stosowne utworzenie jego customowego typu oraz dedykowanych do niego taksonomii. Taksonomie podzieliłem na Kategorie wydarzeń i Tagi wydarzeń. Typy postów to oczywiście ‚Wydarzenia’ ze slugiem ‚wydarzenie’.

Postawiłem sobie za cel, by używając jedynie kodeksu WordPressa, swojej głowy i pomocy szerokiego forum stworzyć mechanizm przypominający kalendarz przyszłych wydarzeń. Pierwsze co mi przyszło do głowy to możliwe statusy postów. Istnieje taki status jak Zaplanowane. Ale czy można opublikować zaplanowane posty?

Oczywiście, że tak. Z pomocą przychodzi nam WP_Query. Pierwsza rzecz. Zawsze tworzenie strony zaczynam od projektu graficznego strony głównej, a potem w miarę złożoności innych podstron. Tak samo jest z wdrażaniem, a więc na stronie głównej potrzebowałem wyświetlić 6 linków do wpisów zaplanowanych (oczywiście z obrazkiem wyróżniającym, datą wydarzenia, kategorią i nazwą). Mechanizm polegał na tym, że kiedy wpis zmieniał status na „Opublikowany” – znikał.

<div class="row">
<?php
  $args = array( 'post_type' => 'wydarzenie', 'posts_per_page' => 6, 'orderby' => 'date', 'order' => 'ASC', 'post_status' => 'future' );
  $loop = new WP_Query( $args );
        while ( $loop->have_posts() ) : $loop->the_post(); ?>

                                        <div class="col-md-4">
                                        <div class="col-cont">
                                        <div class="bg-img" style="background-image:url('<?php echo wp_get_attachment_url( get_post_thumbnail_id( $post->ID ) ); ?>');">
                       <div class="info-future">
  <div class="categ"><?php echo get_the_term_list( $post->ID, 'kategoria_wydarzenia', '<span class="katw_item">', ', ', '</span>' ) ?></div>
             <div class="title"><?php the_title(); ?></div>
    <div class="time"><?php echo get_the_date('j F Y, G:i'); ?></div>
                                        </div>
   <a class="zobacz" href="<?php the_permalink(); ?>">Zobacz więcej</a>
                                        </div>
                                        </div>

                                                    </div>


<?php endwhile; ?>
</div>

Jako, że w widokach samych wpisów był sidebar. Chciałem też umieścić tam widżet wyświetlający nadchodzące wydarzenia. Zrobiłem to przez utworzenie shortcode w functions.php motywu.

function wpb_upcoming_posts() {
	// The query to fetch future posts
	$the_query = new WP_Query(array(
		'post_type' => 'wydarzenie',
		'post_status' => 'future',
		'posts_per_page' => 3,
		'orderby' => 'date',
		'order' => 'ASC'
	));

// The loop to display posts
if ( $the_query->have_posts() ) {
	echo '<section class="widget">';
	echo '<h2 class="widget-title">Nadchodzące</h2>';
	echo '<ul>';
	while ( $the_query->have_posts() ) {
		$the_query->the_post(); ?>
		<li><?php the_title(); ?></li>
	<?php }
	echo '</ul>';
	echo '</section>';
}
wp_reset_postdata();
}
// Add shortcode
add_shortcode('upcoming_posts', 'wpb_upcoming_posts');
// Enable shortcode execution inside text widgets
add_filter('widget_text', 'do_shortcode');

I pojawił się problem. Nie mogłem wyświetlać zaplanowanych wpisów w widokach archiwów. Na przykład po kliknięciu w przypisaną do niego kategorię wydarzenia lub tag.

Nie wyświetlały się wpisy zaplanowane w wynikach wyszukiwania, a co najważniejsze – same widoki wpisów. Znalazłem podobne rozwiązanie na forach internetowych, lecz musiałem je dostosować i uzupełnić o określone warunki. Ten kod też wklejamy do functions.php.

<?php function future_publish( $query ) {
$taxonomy_names = get_object_taxonomies( 'wydarzenie' );
if ( $query->is_main_query() && ( is_post_type_archive('wydarzenie') || is_tax('kategoria_wydarzenia') || is_tax('tag_wydarzenia') || is_single() || is_search() ) ) {
$query->set( 'post_type', array( 'post', 'wydarzenie' ) );
$query->set( 'orderby', 'date' );
$query->set( 'order', 'DESC' );
$query->set( 'post_status', array('future', 'publish') );
} 
}