Support

Account

Home Forums ACF PRO Get Next Post

Solving

Get Next Post

  • I read this post: https://support.advancedcustomfields.com/forums/topic/get-post-with-the-next-date-acf-field-from-now/ on how I can post the next event, but the next event doesn’t seem to be displaying:

    <?php
                                // vars
    							$next_event_query = new WP_Query(array(
    							  'post_type'      => 'event',
    							  'post_status'    => 'publish',
    							  'posts_per_page' => -1,
    							  'meta_query'     => array(
    								array(
    								  'key'        => 'event_date',
    								  'compare'    => '>',
    								  'value'      => $tradeshowsdate,
    								  'type'       => 'DATE'
    								)
    							  ),
    							  'orderby'        => 'meta_value_num',
    							  'order'          => 'ASC'
    							));
                                $rows = get_field('tradeshows', 40);
    							$tradeshowsdate = get_sub_field('event_date', 40);
                                $tradeshowslocation = get_sub_field('event_location', 40);
                        ?>
                          	<?php if ($next_event_query->have_posts()) while ($next_event_query->have_posts()): $next_event_query->the_post(); ?>
                            <div class="col-sm-3">
                             	<h3>NEXT TRADESHOW</h3>
                                <p><?php the_sub_field('event_date'); ?></p>
                             </div>
                             <?php endwhile; ?>  

    There’s no error. There’s just no data displaying for ” the_sub_field(‘event_date’)”.

  • Updated code, but still not record displaying:

               <?php if(get_field('tradeshows', 40) ): ?>
                        <div class="trades container">
                            <?php
                                // vars
    							$current_event_date = get_sub_field('event_date');
    							$next_event_query = new WP_Query(array(
    							  'post_type'      => 'events',
    							  'post_status'    => 'publish',
    							  'posts_per_page' => -1,
    							  'meta_query'     => array(
    								array(
    								  'key'        => 'event_date',
    								  'compare'    => '>',
    								  'value'      => $current_event_date,
    								  'type'       => 'DATE'
    								)
    							  ),
    							  'orderby'        => 'meta_value',
    							  'order'          => 'ASC'
    							));
                                $rows = get_field('tradeshows', 40);
    							//$tradeshowsdate = get_sub_field('event_date', 40);
                                $tradeshowslocation = get_sub_field('event_location', 40);
                        ?>
                          	<?php if ($next_event_query->have_posts()) while ($next_event_query->have_posts()): $next_event_query->the_post(); ?>
                            <div class="col-sm-3">
                             	<h3>NEXT TRADESHOW</h3>
                                <p><?php echo $current_event_date; ?></p>
                             </div>
                             <?php endwhile; ?> 
    
    <?php endif; ?>
  • Your code does not make any sense to me at all, can’t really figure out what your doing.

    assuming that this is checking to see if a repeater has a value

    
    if(get_field('tradeshows', 40) ):
    

    you get a sub field of the current post, however, I do not see any have_rows() loops, so this should return false, unless this loop starts somewhere before the code you’ve included. https://www.advancedcustomfields.com/resources/have_rows/

    
    $current_event_date = get_sub_field('event_date');
    

    Then you do a query based on that value, after the query you have

    
    $rows = get_field('tradeshows', 40);
    $tradeshowslocation = get_sub_field('event_location', 40);
    

    which is getting the value for the same field you checked to make sure it had a value and then you’re getting a sub field of that repeater, but once again, I don’t see any have_rows() loop.

    Then you start looping through your custom query

    
    <?php if ($next_event_query->have_posts()) while ($next_event_query->have_posts()): $next_event_query->the_post(); ?>
    

    At this point, any calls to ACF functions will assume that the post you want to get values from is this post from the custom query and not the original post you were getting values from before the loop. At the same time you’re not even trying to get any values from this new post to display them.

    Your code should go in a sequence that looks something like this, that is if you are looping through a repeater to get information for doing the query.

    
    if (have_rows('repeater')) {
      while (have_rows('repeater')) {
        the_row();
        $current_event_date = get_sub_field('event_date');
        // do your custom query
        // .........
        if ($next_event_query->have_posts()) {
          while ($next_event_query->have_posts()) {
            $next_event_query->the_post();
            // get values and display information about this post
            // of the custom query
          } // end while have posts
          wp_reset_postdata(); // important
        } // and if have posts
      } // end while have rows
    } // end if have rows
    
  • What I’m trying to do is the following (attachment).

    At first with my original code, the content on the right posted fine. It’s content on the left (the next post) is where I was not getting content.

    After reading your post and modifying my code, now I’m not getting ANY data posting.

    
    <?php if( have_rows('tradeshows', 40) ): ?>
                	<?php while( have_rows('tradeshows', 40) ): the_row(); ?>
    
    <?php
    $current_event_date = get_sub_field('event_date');
    							$next_event_query = new WP_Query(array(
    							  'post_type'      => 'events',
    							  'post_status'    => 'publish',
    							  'posts_per_page' => -1,
    							  'meta_query'     => array(
    								array(
    								  'key'        => 'event_date',
    								  'compare'    => '>',
    								  'value'      => $current_event_date,
    								  'type'       => 'DATE'
    								)
    							  ),
    							  'orderby'        => 'meta_value',
    							  'order'          => 'ASC'
    							));
                                $rows = get_field('tradeshows', 40);
                                $tradeshowslocation = get_sub_field('event_location', 40);
    
    if ($next_event_query->have_posts()) while ($next_event_query->have_posts()): $next_event_query->the_post(); ?>
                      
                          <div class="trades container">
                                <div class="col-sm-3">
                                    <h3>NEXT TRADESHOW</h3>
                                    <p><?php echo $current_event_date; ?></p>
                                 </div>
                                 
                                  <div class="col-sm-6 col-sm-offset-3">        
                                    <h3>UPCOMING TRADESHOWS</h3>                         
                                        <div class="col-sm-4">                       
                                            <p class="eventdate"><?php the_sub_field('event_date'); ?><br />
                                            <span class="locplace"><?php the_sub_field('event_location'); ?></span></p>
                                        </div>                                                        
                                  </div> 
                            </div>
    <?php endwhile; ?>
                      <?php  wp_reset_postdata(); ?>
    <?php endwhile; ?>
               <?php endif; ?>
  • Now that I’m looking at all the code I can tell more.

    Fist problem, do not set the meta type to DATE. ACF does not store date fields as a proper MySQL date value. This should either be NUMERIC or CHAR, CHAR it the default so you can remove it or set it to NUMERIC

    You need to set meta_key argument in your query if you’re going to use 'orderby' => 'meta_value', setting a meta_query value is not the same as the meta_key argument.

    Second problem, this if block is not properly formatted
    if ($next_event_query->have_posts())
    there’s no colon and no endif statement

    The next problem I see is here

    
    $tradeshowslocation = get_sub_field('event_location', 40);
    

    and here

    
    <p class="eventdate"><?php the_sub_field('event_date'); ?><br />
    <span class="locplace"><?php the_sub_field('event_location'); ?></span></p>
    

    Inside the loop for your custom query ACF will be looking to get values from the post in the current loop and not the original post. The have_rows() loop in your code is looking at the original post and there is not have_rows() loop for these sub fields, so I’m still not sure where you’re trying to get field values from in your custom query loop.

  • With this code, I’m able to get the right column to post:

    <?php if( have_rows(‘tradeshows’, 40) ): ?>
    <?php
    $current_event_date = get_sub_field(‘event_date’);
    $next_event_query = new WP_Query(array(
    ‘post_type’ => ‘events’,
    ‘post_status’ => ‘publish’,
    ‘posts_per_page’ => -1,
    ‘meta_query’ => array(
    array(
    ‘key’ => ‘event_date’,
    ‘compare’ => ‘>’,
    ‘value’ => $current_event_date,
    ‘type’ => ‘CHAR’
    )
    ),
    ‘orderby’ => ‘meta_value’,
    ‘order’ => ‘ASC’
    ));

    $rows = get_field(‘tradeshows’, 40);
    ?>

    <?php if ($next_event_query->have_posts()) : while ($next_event_query->have_posts()): $next_event_query->the_post(); ?>
    <div class=”col-sm-3″>
    <h3>NEXT TRADESHOW</h3>
    <p><?php echo $current_event_date; ?></p>
    </div>
    <?php wp_reset_postdata(); ?>
    <?php endwhile; ?>
    <?php endif; ?>

    <div class=”col-sm-6 col-sm-offset-3″>
    <h3>UPCOMING TRADESHOWS</h3>
    <?php while( have_rows(‘tradeshows’, 40) ): the_row(); ?>
    <div class=”col-sm-4″>
    <p class=”eventdate”><?php the_sub_field(‘event_date’); ?><br />
    <span class=”locplace”><?php the_sub_field(‘event_location’); ?></span></p>
    </div>
    <?php endwhile; ?>
    </div>
    <?php endif; ?>

    I don’t understand how to create a ‘meta_key’ argument as you’ve mentioned since I need to retrieve the next post in the list. I’m assuming you mean this:

    $next_event_query = new WP_Query(array(
    							  'post_type'      => 'event',
    							  'post_status'    => 'publish',
    							  'posts_per_page' => -1,
    							  'meta_query'     => array(
    								array(
    								  'meta_key'   => 'event_date',
    								  'key'        => 'event_date',

    The below code posts the data in the right column within the loop that I have set:

    <p class="eventdate"><?php the_sub_field('event_date'); ?><br />
    <span class="locplace"><?php the_sub_field('event_location'); ?></span></p>

    So I’m still needing to understand how to post the next post in the left column.

  • 
    
    $next_event_query = new WP_Query(array(
    	'post_type'      => 'events',
    	'post_status'    => 'publish',
    	'posts_per_page' => -1,
    	'meta_query'     => array(
    		array(
    			'key'        => 'event_date',
    			'compare'    => '>',
    			'value'      => $current_event_date,
    		)
    	),
    	'meta_key'       => 'event_date',
    	'orderby'        => 'meta_value',
    	'order'          => 'ASC'
    ));
    

    I’m not sure about your second question. Can you post the code that you have now using code tags to it’s easier to read.

  • Here is the code in the entirety. The content on the right posts, but I’m still not getting the next post for the left column:

    		<?php if( have_rows('tradeshows', 40) ): ?>
                <?php
    				$current_event_date = get_sub_field('event_date');
    				$next_event_query = new WP_Query(array(
    							  'post_type'      => 'event',
    							  'post_status'    => 'publish',
    							  'posts_per_page' => -1,
    							  'meta_query'     => array(
    								array(
    								  'key'        => 'event_date',
    								  'compare'    => '>',
    								  'value'      => $current_event_date,
    								)
    							  ),
    							  'meta_key'	   => 'event_date',
    							  'orderby'        => 'meta_value',
    							  'order'          => 'ASC'
    							));
    				
    				$rows = get_field('tradeshows', 40);
    				?>
                    
    				<div class="trades">
    					<?php if ($next_event_query->have_posts()) : while ($next_event_query->have_posts()): $next_event_query->the_post(); ?>
                            <div class="col-sm-3">
                             	<h3>NEXT TRADESHOW</h3>
                                <p><?php echo $current_event_date; ?></p>
                             </div>
                     <?php wp_reset_postdata(); ?>
               		<?php endwhile; ?>
                    <?php endif; ?>
                    
                            <div class="col-sm-6 col-sm-offset-3">        
                            <h3>UPCOMING TRADESHOWS</h3>
                            <?php while( have_rows('tradeshows', 40) ): the_row();  ?>   
                                    <div class="col-sm-4">                       
                                        <p class="eventdate"><?php the_sub_field('event_date'); ?><br />
                                        <span class="locplace"><?php the_sub_field('event_location'); ?></span></p>
                                    </div>                                                          
                            <?php endwhile; ?>   
                            </div>
                     </div>                    		
          <?php endif; ?>
    </div>
  • I’ve looked at your code a couple of times and to be honest, I can’t really figure out what you’re trying to do. This is your code with the white space cleaned up so I could see what’s going on a little better and some comments.

    
    <?php 
      if (have_rows('tradeshows', 40)):
        // this field is getting nothing
        // because there is no while(have_rows()) loop or call to the_row()
        // since $current_event_date has a value of NULL the query will not return anything
        // or maybe since the value is NULL it returns all posts
        // not really sure here
        $current_event_date = get_sub_field('event_date');
        $next_event_query = new WP_Query(array(
          'post_type'      => 'event',
          'post_status'    => 'publish',
          'posts_per_page' => -1,
          'meta_query'     => array(
          array(
            'key'        => 'event_date',
            'compare'    => '>',
            'value'      => $current_event_date,
          )
          ),
          'meta_key'     => 'event_date',
          'orderby'        => 'meta_value',
          'order'          => 'ASC'
        ));
        // not sure why we're getting this field here
        // this variable is never used
        $rows = get_field('tradeshows', 40);
        ?>
          <div class="trades">
            <?php 
              if ($next_event_query->have_posts()) : 
                // this is looping through the posts of the nested query
                // show values associated with those posts
                // if the query above returns nothing then this will never run
                while ($next_event_query->have_posts()): 
                  $next_event_query->the_post(); 
                  ?>
                    <div class="col-sm-3">
                      <h3>NEXT TRADESHOW</h3>
                      <p><?php echo $current_event_date; ?></p>
                    </div>
                  <?php 
                endwhile;
                wp_reset_postdata();
              endif;
            ?>
            <div class="col-sm-6 col-sm-offset-3">        
              <h3>UPCOMING TRADESHOWS</h3>
              <?php 
                while (have_rows('tradeshows', 40)): 
                  // this is looping through the original repeater
                  // to show subfield of this field for post ID = 40
                  the_row();
                  ?>   
                    <div class="col-sm-4">                       
                        <p class="eventdate"><?php the_sub_field('event_date'); ?><br />
                        <span class="locplace"><?php the_sub_field('event_location'); ?></span></p>
                    </div>                                                          
                  <?php 
                endwhile;
              ?>   
            </div>
          </div>                        
        <?php 
      endif;
    ?>
    

    Looking back over everything, I honestly can’t tell how the event date in post 40 is related to the “event_date” in your query where you’re trying to get the posts, or what type of field that is or how it should be queried. Is it another sub field of a repeater in those other posts? Is it a top level field? Why is <?php if( have_rows('tradeshows', 40) ): ?> looking at post ID 40 in the first place?

    The first thing you need to do is to go back to a point where the loop for the repeater is working, showing the current values of that repeater and then explain what it is you’re trying to query for in the other posts. Like I said, is it a top level field? is it a sub field of a repeater?

  • I’m trying to have on the left column the next upcoming event and have the other events post on the right column. The left column data is what’s missing. The right column data is not having a problem posting.

    <?php if( have_rows('tradeshows', 40) ): ?>
    //This is a repeater field, and I'm getting values from another post:
    //https://www.advancedcustomfields.com/resources/how-to-get-values-from-another-post/

    ‘event_date’ is a sub field. I’ve attached screenshots of my setup.

  • The next event from the current event shown, or the next event in general?

    For example:
    1) you’re showing event A and the next one after this event is event B
    2) today is Nov 18 and the next event in Nov 20

    And now that I understand that you’re trying to query a sub field of a flexible content field, that just makes things more difficult. You can’t just query sub fields.

    Let’s say that the value you want is in the first row of the repeater or flex field, the actual meta key will be “repeater_field_name_0_event_date” or “flex_field_name_0_event_date” where the “0” represents the row number starting at zero.

    There is a section on this page that explains it https://www.advancedcustomfields.com/resources/query-posts-custom-fields/ and there are many topics here that talk about it. I will not be able to help you with this, because I avoid querying sub fields at all costs, it involves a ridiculous amount of work and testing to get it right that will constantly be breaking or need tweaking to keep it working.

    answer my first question and I’ll see if I can think of a work around for querying sub fields for what you want to do.

  • To answer your question, I’m thinking it would be #2.

    Logically the event_date subfield would have to compare it’s date to today’s date and post the next upcoming event in the left column until that event date has passed. Once that has passed, then the next event date would post in the left column until it’s expiration. All other dates would be posting on the right.

    If ACF is going to be an issue with posting such a repeater in this manner, what would you recommend? A different plugin? A different ACF Field method?

  • The first thing that I would do is store these event dates into something that can more easily be searched in a simple meta_query, like I said above, searches based on repeater sub fields are a PITA that I avoid.

    
    <?php 
      
      // step 1: store event_date in a queryable form
      // this is done as a class, the reason is storage of
      // each value that has been saved
      class store_repeater_sub_field_in_standard_wp_meta {
        
        // this array will store values that have already been saved
        // more about this later
        private $fields = array();
        
        public function __construct() {
          // this is where we add the filters
          // use the field keys here because it is a sub field
          // this class will work on multiple fields by adding the
          // filter multiple times, once for each field key
          // all values stored into new fields will be identical to values stored by ACF
          add_filter('acf/update_value/key=field_123456', array($this, 'convert_sub_field'), 10, 3);
        } // end public function __construct
        
        public function convert_sub_field($value, $post_id, $field) {
          // get the field key
          $field_key = $field['key'];
          // get the field name
          $field_name = $field['name'];
          // create a new field name based on the current field name
          $queryable_name = 'queryable_'.$field_name;
          
          // first step is to see if we've already saved any values for this field
          if (!isset($this->fields[$field_key])) {
            // there is not value set in the property for this key
            // no values have been updated yet
            // clear any existing values from the queryable field
            delete_post_meta($post_id, $queryable_name);
            // add a nested array to the property to hold values
            // for this field, this will also ensure that we don't
            // delete them again since the field has a value in the property
            $this->fields[$field_key] = array();
          }
          // see if we've already saved this value for this field
          // there really is not point saving the same value twice
          if (!in_array($value, $this->fields[$field_key])) {
            // not there, add it the values
            $this->fields[$field_key][] = $value;
            // and add it to the database
            add_post_meta($post_id, $queryable_name, false);
            // the last argument above says that this is not a unique meta key
            // and will hold multiple values
          }
          // return the original value for ACF to process as normal
          return $value;
        } // end public function convert_sub_field
        
      } // end class store_repeater_sub_field_in_standard_wp_meta
      
      // instantiate the object
      new store_repeater_sub_field_in_standard_wp_meta();
      
    ?>
    

    I know that what is above can seem extreme, but this was fairly easy to do (if you remove all the comments there is actually very little code there) and now we can construct extremely simple queries instead of complex LIKE queries and adding filters to add LIKE to the meta_key part of the query because we are querying a sub field.

    
    // current date
    $current_date = date{'Ymd');
    // get the next event from now
    $args = array(
      'post_type' => 'event',
      'post_status' => 'publish',
      'posts_per_page' => 1, // or the number of next dates you want
      'meta_key' => 'queryable_event_date',
      'order_by' => 'meta_value',
      'order' => 'ASC',
      'meta_query' => array(
        'key' => 'queryable_event_date',
        'value' => $date,
        'compare' => '>='
      ),
    );
    $next_event_query = new WP_Query($args);
    

    during the loop for the “next_event” query, collect a list of posts show so that they are not returned in the next query.

    
    // other code before loop
    $events_shown = array();
    if ($next_event_query->have_posts()) {
      while ($next_event_query->have_posts()) {
        $next_event_query->the_post();
        $events_shown[] = $post->ID;
        // other code to display the next event post
      }
      wp_reset_postdata()
    }
    

    Then use the values collected in $events_shown to not get those events again

    
    $args = array(
      'post_type' => 'event',
      'post_status' => 'publish',
      'posts_per_page' => 1, // or the number of next dates you want
      'meta_key' => 'queryable_event_date',
      'order_by' => 'meta_value',
      'order' => 'ASC',
      'meta_query' => array(
        'key' => 'queryable_event_date',
        'value' => $date,
        'compare' => '>='
      ),
      'posts__not_in' => $events_shown,
    );
    $event_query = new WP_Query($args);
    

    I’m sure that you could also construct a single query and loop to do this, but I tend toward a less complex coding style that lets me more easily understand what I was thinking when I need to look at it again in a year because something needs to be changed.

    Hope this helps

Viewing 14 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic.