1

I have a query (see below) that gives a list of 10 news items ordered by the meta value "event_date" and filtered so that only posts earlier than today are displayed. This query is taking two seconds to process, so I am looking for a simple way to cache the results to get the load time faster. I already use WPEngine so I don't need any caching plugins. Thanks in advance for your help.

<?php $today = time();?>
<?php $args = array( 
'numberposts' => 10,
'orderby'       => 'meta_value_num',
'order'         => 'DESC',
'meta_key'      => 'event_date',
'meta_query'    => array(
    array(
        'key' => 'event_date',
        'value' => $today,
        'compare' => '<=',
        'type' => 'NUMERIC'
        )
    )
 );

$postslist = get_posts( $args );

foreach ($postslist as $post) :  setup_postdata($post); ?>

2 Answers 2

9

You can use transient cache to cache your custom query. Here is a simple code to set_transient cache for your query for 12 hours. In 12 hours WordPress will not make new query but fetch posts from transient. On expiration, it will save new query in transient again for next 12 hours.

I have been using transient for many queries on my website but make sure you set expiration time carefully otherwise your new post might not appear on your website for some time.

<?php 

    // Check for transient. If none, then execute Query
    if ( false === ( $postslist = get_transient( 'postslist_query' ) ) ) {

        $args = array(
            'numberposts' => 10,
            'orderby'       => 'meta_value_num',
            'order'         => 'DESC',
            'meta_key'      => 'event_date',
            'meta_query'    => array(
                array(
                    'key' => 'event_date',
                    'value' => $today,
                    'compare' => '<=',
                    'type' => 'NUMERIC'
                )
            )
        );

        $postslist = get_posts( $args );

      // Put the results in a transient. Expire after 12 hours.
      set_transient( 'postslist_query', $postslist, 12 * 60 * 60 );

    }

    foreach ( $postslist as $post ) :  setup_postdata( $post );

?>

read more on Transient API

0
2

I wrapped @Robert-hue's code into a helper method called get_cached_posts, which is a drop-in replacement for get_posts with Transients caching enabled:

/**
 * Gets cached posts for a query. Results are stored against a hash of the
 * parameter array. If there's nothing in the cache, a fresh query is made.
 * 
 * @param Array $args The parameters to pass to get_posts().
 * @return Array List of posts matching $args.
 */
public static function get_cached_posts( $args )
{
    $post_list_name = 'get_posts_' . md5( json_encode( $args ) );

    if ( false === ( $post_list = get_transient( $post_list_name ) ) ) {
        $post_list = get_posts( $args );

        set_transient( $post_list_name, $post_list, 86400 );
    }

    return $post_list;
}

Note: 86400 is one day.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.