Support

Account

Home Forums General Issues List posts by date picker with pagination Reply To: List posts by date picker with pagination

  • It’s not that I’m apposed to sharing, not really anything super secret, but the scope of what I have is too huge to share on a forum.

    In order to get pagination to work correctly you need to use a pre_get_posts filter on on the archive. Or at least that is the easiest way for me to do it. I suppose that you can do it with get_posts(), but it would be more difficult. When you modify the main query then you can use built in WP functions for the pagination links.

    For example, here is my pagination code on one site that uses a simple previous/next link, I use my own function because I wrap the links in bootstrap columns.

    
    function events_nav_links() {
      if (!get_previous_posts_link() && !get_next_posts_link()) {
        return;
      }
      ?>
        <div class="row events-archive-nav" style="margin-bottom: 2em;">
          <div class="col-6 text-left previous">
            <?php previous_posts_link("&laquo; Earlier Events"); ?>
          </div>
          <div class="col-6 text-right next">
            <?php next_posts_link("Later Events &raquo;"); ?>
          </div>
        </div>
      <?php 
    }
    

    This one uses pagination links to show page numbers

    
    // maybe page links
    $current_page = max(1, get_query_var('paged'));
    $args = array(
      'base' => get_pagenum_link(1).'%_%',
      'format' => 'page/%#%/',
      'prev_text' => '<i class="fal fa-chevron-left"></i>',
      'next_text' => '<i class="fal fa-chevron-right"></i>',
      'current' => $current_page,
      'mid_size' => 5,
      'type' => 'array'
    );
    $page_links = paginate_links($args);
    if (!empty($page_links)) {
      ?>
        <div class="row">
          <div class="col-12 event-page-links number-page-links">
            <div class="row justify-content-center">
              <?php 
                foreach ($page_links as $link) {
                  //$link = str_replace('//', '/', $link);
                  $extra_classes = array();
                  if (preg_match('/(prev|next)/', $link)) {
                    $extra_classes[] = 'icon';
                  } elseif (preg_match('/current/', $link)) {
                    $extra_classes[] = 'current';
                  } else {
                    $extra_classes[] = 'page';
                  }
                  $class = '';
                  if (!empty($extra_classes)) {
                    $class = ' '.implode(' ', $extra_classes);
                  }
                  ?>
                    <div class="col-auto link<?php echo $class; ?>">
                      <?php echo $link; ?>
                    </div>
                  <?php 
                }
              ?>
            </div>
          </div>
        </div>
      <?php 
    } // end if page links
    

    Like I said, I don’t know if it’s possible to do something similar using get_posts() in the template, but it will be more difficult. I try to always use built in WP functions when I can and using WP’s built in pagination functions are easier than trying to build something yourself. Altering the main query through a pre_get_posts_filter is just easier.

    the following is a pre_get_psots filter from a site that only shows current and future events in the archive

    
    function events_archive_only_children($query) {
      if (is_admin() || !$query->is_main_query()) {
        return;
      }
      // tests to make sure that we are displaying an event page
      if (!isset($query->query_vars) ||
          !isset($query->query_vars['post_type']) ||
          $query->query_vars['post_type'] != $this->post_type) {
        // test for event-category tax
        if (!isset($query->query_vars) ||
            !isset($query->query_vars['event-category'])) {
          // test for event-tag tax
          if (!isset($query->query_vars) ||
              !isset($query->query_vars['event-tag'])) {
            // test for event-type
            if (!isset($query->query_vars) ||
                !isset($query->query_vars['event-type'])) {
              // text for event-visitor-type
              if (!isset($query->query_vars) ||
                  !isset($query->query_vars['event-visitor-type'])) {
                // not of the possible query vars for events is set
                return;
              }
            }
          }
        }
      }
      // double check we are not on a single page
      if (is_single()) {
        return;
      }
      
      // custom query parameters (custom search form) that might be set
      // if visitor's browser does not support JS
      // redirect to correct URL based on event rewrite rules
      // custom taxonomies include event type and visitor type
      $type = false;
      $visitor = false;
      if (isset($_GET['e-type']) && !empty($_GET['e-type'])) {
        $type = $_GET['e-type'];
      }
      if (isset($_GET['e-visitor']) && !empty($_GET['e-visitor'])) {
        $visitor = $_GET['e-visitor'];
      }
      if ($type || $visitor) {
        $url = '/event/';
        if ($type) {
          $url .= 'type/'.$type.'/';
        }
        if ($visitor) {
          $url .= 'visitor/'.$visitor.'/';
        }
        wp_redirect($url, 301);
        exit;
      }
      
      // posts_per_page
      // setting on options page allows client to set
      if (function_exists('get_field')) {
        $post_id = $this->options_page;
        $posts_per_page = get_field('events_per_page', 'events_options');
        if ($posts_per_page === 0) {
          $posts_per_page = -1;
        }
        $query->set('posts_per_page', $posts_per_page);
      }
      
      // this framework uses parent/child events
      // to allow multiple event start and and dates
      // and recurring events
      // only show child events on the admin
      $query->set('post_parent__not_in', array('0'));
      
      
      if (isset($query->query['year'])) {
        // doing a date query
        // The following converts standard WP date searches
        // into a meta query on start & end dates ACF date/time fields
        // and removes the WP date query
        // shows any event starting in the selected year/month/day
        $date = $query->query['year'].'-';
        unset($query->query['year']);
        $query->query_vars['year'] = '';
        if (isset($query->query['monthnum'])) {
          $date .= $query->query['monthnum'].'-';
          unset($query->query['monthnum']);
          $query->query_vars['monthnum'] = '';
        };
        if (isset($query->query['day'])) {
          $date .= $query->query['day'];
          unset($query->query['day']);
          $query->query_vars['day'] = '';
        };
        $meta_query = array(
          'relation' => 'AND',
          'start_date_clause' => array(
            'key' => 'start_date',
            'value' => $date,
            'compare' => 'LIKE',
          ),
          'end_date_clause' => array(
            'key' => 'end_date',
            'value' => date('Y-m-d H:i:s'),
            'compare' => '>',
            'type' => 'DATETIME'
          )
        );
      } else {
        // not doing a date query
        // add standard meta query to only show current or upcoming events
        $meta_query = array(
          'relation' => 'AND',
          'start_date_clause' => array(
            'key' => 'start_date',
            'compare' => 'EXISTS',
          ),
          'end_date_clause' => array(
            'key' => 'end_date',
            'value' => date('Y-m-d H:i:s'),
            'compare' => '>',
            'type' => 'DATETIME'
          )
        );
      }
      $query->set('meta_query', $meta_query);
      
      // order by start/end date acf fields
      $order = array(
        'start_date_clause' => 'ASC',
        'end_date_clause' => 'ASC',
        'title' => 'ASC'
      );
      $query->set('orderby', $order);
    }