When doing development, I sometimes find I need a custom shortcode which performs a WP_Query. To reduce the load time of this shortcode, you can cache the result using a transient.
Sometimes developers choose to cache the query result and generate the markup each time the shortcode is called. I prefer to cache the final markup.
Example WordPress Shortcode using WP_Query and Caching the Result in a Transient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Shortcode to display query results of CPT query | |
// with transient caching | |
add_shortcode( 'query_results', 'fe_query_results' ); | |
add_action( 'save_post', 'fe_query_results_delete_transient' ); | |
function fe_query_results( $atts ) { | |
global $post; | |
$transient_key = 'fe_query_results_transient_key'; | |
$transient_time = 24 * HOUR_IN_SECONDS; | |
// return transient if it exists | |
if ( false !== ( $output = get_transient( $transient_key ) ) ) { | |
return $output; | |
} | |
$output = ''; | |
$args = array( | |
'post_type' => 'post', | |
'order' => 'ASC', | |
'orderby' => 'menu_order', | |
'posts_per_page' => 200, | |
// re-enable if you need pagination | |
'no_found_rows' => true, | |
// re-enable if you use post meta in your output | |
'update_post_meta_cache'=> false, | |
// re-enable if you use terms in your output | |
'update_post_term_cache'=> false, | |
); | |
$fe_query= new WP_Query( $args ); | |
if ( $fe_query->have_posts() ) { | |
$output .= '<ul class="fe-query-results-shortcode-output">'; | |
while ( $fe_query->have_posts() ) { | |
$fe_query->the_post(); | |
$title = get_the_title(); | |
$link = get_the_permalink(); | |
$output .= "<li><a href=\"{$link}\">{$title}</a></li>"; | |
} | |
$output .= '</ul>'; | |
} else { | |
$output .= '<div class="fe-query-results-shortcode-output-none">No results were found</div>'; | |
} | |
wp_reset_postdata(); | |
set_transient( $transient_key, $output, $transient_time ); | |
return $output; | |
} | |
function fe_query_results_delete_transient() { | |
global $post; | |
if ( $post && 'post' === $post->post_type ) { | |
delete_transient( 'fe_query_results_transient_key' ); | |
} | |
} |
Hi Sal,
Very interesting, I will definitely be using this technique in future.
One question though, if passing parameters from the shortcode (like in [the gist] below) would these be cached in the transient also:
https://gist.github.com/salcode/24a6e02ce48218e14011
Hi Paul,
In this code, I’m caching the output html. If you change the parameters of the query (whether in code or via Shortcode parameters in your example), these updated parameters will NOT be visible until the transient expires (in this case in 24 hours) or the transient is deleted.