Support

Account

Home Forums Front-end Issues Displaying posts using a custom date field

Solving

Displaying posts using a custom date field

  • Hi All,

    I’m working on a website that people can contribute to by posting art events. (http://dailycapital.com.au).

    I modified the “post” post type using custom fields and added fields like event start date, end date, description, cost .etc.

    Now, the problem is I need to sort the events (posts) based on not wordpress post dates, but one of my own custom fields named “start_date”.

    My post page is below. How can I modify the code to be able to display posts based on contents of the custom field “start_date”?

    Thanks
    K

    <?php
    /**
     * The default template for displaying content
     *
     * Used for both single and index/archive/search.
     *
     *
     */
    ?>
    
    <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    	<?php twentyfourteen_post_thumbnail(); ?>
    
    	<header class="entry-header">
    		<?php if ( in_array( 'category', get_object_taxonomies( get_post_type() ) ) && twentyfourteen_categorized_blog() ) : ?>
    			<div class="entry-meta">
    				<span class="cat-links"><?php echo get_the_category_list( _x( ', ', 'Used between list items, there is a space after the comma.', 'twentyfourteen' ) ); ?></span>
    			</div>
    			<?php
    			endif;
    
    			if ( is_single() ) :
    				the_title( '<h1 class="entry-title">', '</h1>' );
    			else :
    				the_title( '<h1 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h1>' );
    			endif;
    			?>
    			<?php
    /*
    MBD Event information display
    */
    ?>
    
    <?php
    if(function_exists('email_link')) { email_link(); }
    ?>
    
    	<?php
    	if( get_field('start_date') ):
    		echo ('<b>Start Date: </b>');
    	$date = DateTime::createFromFormat('Ymd', get_field('start_date'));
    	echo ('<span style="background-color:yellow">');
    	echo $date->format('d/m/Y');
    	echo ('</span>');
    	endif;
    	?>
    </br>
    <?php
    if( get_field('end_date') ):
    	echo ('<b>End Date: </b>');
    echo ('<span style="background-color:yellow">');
    $date = DateTime::createFromFormat('Ymd', get_field('end_date'));
    echo $date->format('d/m/Y');
    echo ('</span>');
    endif;
    ?>
    
    <b>Description: </b></br>
    	
    		<?php
    		the_field('description');
    		?>
    	
    
    <b>Cost: </b></br>
    	<?php
    	the_field('cost');
    	?>
    
    <b>Telephone: </b>
    	<a href="tel:<?php the_field('telephone');?>"><?php the_field('telephone');?></a>
    
    <b>Website: </b>
    	<a href="<?php the_field('web');?>"><?php the_field('web');?></a>
    
    <b>Photo Credits: </b>
    	<?php
    	the_field('photo_credits');
    	?>
    
    <b>Location: </b>
    	<?php
    	the_field('location');
    	?>
    
    <?php
    if(get_field('address_on_map') ):
    
    	echo ('<b>On Map: </b><br><br>');
    
    $mbd_address=get_field('address_on_map');
    
    echo ('<iframe width="400" height="300" frameborder="0" style="border:0" src="https://www.google.com/maps/embed/v1/place?key=AIzaSyAbHtCKUQU4V0AxeP-dcbR1_2jrUWOeb3Q&q=').$mbd_address['address'].('"allowfullscreen></iframe>');
    
    endif;
    
    ?>
    <?php
    /*
    END MBD Event information display
    */
    ?>
    <div class="entry-meta">
    	<?php
    	if ( 'post' == get_post_type() )
    		twentyfourteen_posted_on();
    
    	if ( ! post_password_required() && ( comments_open() || get_comments_number() ) ) :
    		?>
    	<span class="comments-link"><?php comments_popup_link( __( 'Leave a comment', 'twentyfourteen' ), __( '1 Comment', 'twentyfourteen' ), __( '% Comments', 'twentyfourteen' ) ); ?></span>
    	<?php
    	endif;
    
    	edit_post_link( __( 'Edit', 'twentyfourteen' ), '<span class="edit-link">', '</span>' );
    	?>
    </div><!-- .entry-meta -->
    </header><!-- .entry-header -->
    
    <?php if ( is_search() ) : ?>
    	<div class="entry-summary">
    		<?php the_excerpt(); ?>
    	</div><!-- .entry-summary -->
    <?php else : ?>
    	<div class="entry-content">
    		<?php
    	
    		/* translators: %s: Name of current post */
    		the_content( sprintf(
    			__( 'Continue reading %s <span class="meta-nav">&rarr;</span>', 'twentyfourteen' ),
    			the_title( '<span class="screen-reader-text">', '</span>', false )
    			) );
    
    		wp_link_pages( array(
    			'before'      => '<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'twentyfourteen' ) . '</span>',
    			'after'       => '</div>',
    			'link_before' => '<span>',
    			'link_after'  => '</span>',
    			) );
    			?>
    
    		</div><!-- .entry-content -->
    	<?php endif; ?>
    
    	<?php the_tags( '<footer class="entry-meta"><span class="tag-links">', '', '</span></footer>' ); ?>
    </article><!-- #post-## -->
  • You should not alter the template because that’s really not needed. You should alter the way that posts are ordered is to create a pre_get_posts filter https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts and add a meta_query to it.

    You would put this in your functions.php file

    
    function my_pre_get_posts($query=false) {
      if (is_admin() || !$query || !is_a($query, 'WP_Query') ||
        !$query->is_main_query()) {
        return;
      }
      if (isset($query->query_vars['post_type']) &&
          $query->query_vars['post_type'] == 'post') {
        $query->set('meta_key', 'start_date');
        $query->set('meta_type', 'DATE');
        $query->set('orderby', 'meta_value');
        $query->set('order', 'ASC');
      }
    }
    add_action('pre_get_posts', 'my_pre_get_posts');
    
  • Thanks John,

    I’ve used the code in my functions.php (as well as reading about it to understand what it is doing), but it doesn’t work. (No sorting happens).

    FYI I’m working on a child theme and put your function into the functions.php of the child theme.

    Any ideas?

    Thanks,
    K

  • What kind of a field is it, other than a date field, is it part of a repeater or something?

  • Hi John,

    Thanks for reply and sorry for the delay.

    It’s not just one field. It’s a set of fields. I’ve modified the standard post. Please see the following page: http://dailycapital.com.au/canberra_events/venice-the-golden-age-presented-by-oriana-chorale/

    You will notice that almost all fields (start date, end date, address on map, cost, etc) except the event title itself is from ACF. (The event title is actually the post title).

    And no , it’s not a part of a repeater.

    Thank you very much in advance for your help.
    K

  • If the fields are not part of a repeater or some special field type, for example the date fields are just date pickers, number fields are just numbers, there are no checkboxes or multiselect fields that store data in serialized arrays, then you are just sorting by multiple postmeta fields.

    There was a new feature added to WP in 4.2 that allows you to do this. I don’t know if it’s made it into the documentation. This page explains it. https://make.wordpress.org/core/2015/03/30/query-improvements-in-wp-4-2-orderby-and-meta_query/

    And like I said, you need to modify the main query to change the order. This is done using pre_get_posts https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts

    Here is a posts on stack exchange that shows how to use pre_get_posts an order the posts by a single meta value http://wordpress.stackexchange.com/questions/141355/wordpress-screwing-up-orderby-meta-value-num-in-pre-get-posts

  • Hi John,

    Still working on this and try to understand it line by line.

    Regarding this code that you suggested before:

    function my_pre_get_posts($query=false) {
    if (is_admin() || !$query || !is_a($query, ‘WP_Query’) ||
    !$query->is_main_query()) {
    return;
    }

    if (isset($query->query_vars[‘post_type’]) &&
    $query->query_vars[‘post_type’] == ‘post’) {

    $query->set(‘meta_key’, get_field(‘start_date’));
    $query->set(‘meta_type’, ‘DATE’);
    $query->set(‘orderby’, ‘meta_value’);
    $query->set(‘order’, ‘DESC’);
    }
    }
    add_action(‘pre_get_posts’, ‘my_pre_get_posts’);

    1-Is it correct that I used:
    get_field(‘start_date’)

    to get the my custom field value? , or I just should use ‘start_date’ ?

    2- I’ve noticed nothing works unless when I remove the following if clause:

    if (isset($query->query_vars[‘post_type’]) &&
    $query->query_vars[‘post_type’] == ‘post’) {

    When I remove the if clause above, code seems to alter the post order, but couldn’t find out based on what?

    3- Inside ACF plugin panel, and regarding that ‘start_date’ custom form value, I’ve set its “save format” as yymmdd, and display format as dd/mm/yy

    Can it be a possibility that sorting doesn’t work because of display format is dd/mm/yy?

    Many Thanks,
    K

  • 1- it should be just start_date. That is the meta key which is the same as the field name.

    2 – You should change the check to check for your post type that way the query is only changed for your post type.

    
    
      if (isset($query->query_vars['post_type']) &&
          $query->query_vars['post_type'] == 'your-post-type-here') {
    

    3- You must be using ACF4. ACF 5 has a Display Format and Return Format and always stores all dates as YYYYMMDD. You will need to alter your save format to something that is recognized as a date by WP. Either that or you’ll need to set the meta type to CHAR or NUMBER I think.

    When posting code you should put it inside back ticks, or use the code button at the top of the reply box, makes it a lot easier to read.

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

The topic ‘Displaying posts using a custom date field’ is closed to new replies.