Atomic Smash homepage splash

How to clear your WordPress cache after saving a custom post

Words by David DarkeNovember 27, 2017

WordPress is a lightweight CMS, out the box (with a good theme) it’s very easy to build a fast and effective website. Yet as the website and traffic increases, it’s important to make sure the page load speed (and user experience) is maintained.

You can always just increase the server/hosting power, but adding caching layers if more flexible and vastly more cost-effective. We dive into installing a cache in this post.

Our caching plugin of choice is W3 Total Cache:

It bundles a large number of caching approaches and options. It can help with page, database and object caching as well as thing like adding a content delivery network. On a recent project however, we came across an issue specifically with page caching.

Understanding page caching

Page caching takes any page, simple or complicated and captures the HTML that is outputed by WordPress. It then saves this output for when the next user visits that same page. Database queries can be dramatically reduced by using page caching. Here is an example from a website that we recently launched:

Within this section from the top of the tifofootball.com homepage, it can be broken down into the individual database queries that make up the page (highlighted in red):

So just this section relies on at least 12 content queries to output. In fact, there are usually far more than this for background functionality etc. With page caching enabled, these small queries can be converted into one big query asking just for the HTML output:

This is vastly more efficient and comes with a multitude of options and ways to optimise. For example, if your database server is struggling, cached objects can be stored on the hard drive or even in the server’s ram and vica versa.

One other benefits of having this output saved, is the ability to compress optimise before it’s sent to the end user.

Our issue

The problem we faced we being able to clear key content pages when a custom post type (called ‘feature’) was being saved. We found that when saving a ‘feature’, the content would be live and visible if you navigated to it directly, but you couldn’t access it from keys areas, like the features archive, homepage or even author pages.

W3 total cache handles this very well for ‘pages’ and ‘posts’, but not for custom post types. There are also options through its admin interface to selectively clear pages, but again, these just didn’t seem to work for custom post types.

Our solution was to use a snippet found from this conversation on the WordPress support forum:

$custom_post_types = array( "<Your Post type Slug Here>" => "<Optional: Your Archive Slug Here>");
$max_archive_pages = 0;	// 0 == all archive page #s

function post_status( $new_status, $old_status, $post )
{
	global $custom_post_types, $max_archive_pages;

	if ( array_key_exists( $post->post_type, $custom_post_types ) && ( $new_status === "publish" || $old_status === "publish" ) )
	{
		if ( defined( 'W3TC' ) )
		{
			$archive = empty( trim( $custom_post_types[$post->post_type] ) ) ? $post->post_type:trim( $custom_post_types[$post->post_type] );

			$post->post_status = "";
			$link = preg_replace( '~__trashed/$~', '/', get_permalink( $post ) );
			w3tc_flush_url( $link );

			$posts_per_page = get_option( 'posts_per_page' );
			$posts_number = \W3TC\Util_PageUrls::get_archive_posts_count( 0, 0, 0, $post->post_type );
			$posts_pages_number = @ceil( $posts_number / $posts_per_page );

			if ( $max_archive_pages > 0 && $posts_pages_number > $max_archive_pages ) {
				$posts_pages_number = $max_archive_pages;
			}

			if ( $posts_pages_number == 0 ) {
				w3tc_flush_url( \W3TC\Util_Environment::home_domain_root_url() . "/" . $archive );
			} else {
				for ( $pagenum = 1; $pagenum <= $posts_pages_number; $pagenum++ ) {
					$link = \W3TC\Util_PageUrls::get_pagenum_link( $archive, $pagenum );
					w3tc_flush_url( $link );
				}
			}
		}
	}
}
add_action(  'transition_post_status',  'post_status', 10, 3 );

By defining your post types at the top of the block, you can selectively clear cached pages when they are created, updated or even deleted.

There is also a more blunt approach:

$custom_post_types = array( "<Your Post type Slug Here>" => "<Optional: Your Archive Slug Here>");
$max_archive_pages = 0;	// 0 == all archive page #s

function post_status( $new_status, $old_status, $post )
{
	global $custom_post_types, $max_archive_pages;

	if ( array_key_exists( $post->post_type, $custom_post_types ) && ( $new_status === "publish" || $old_status === "publish" ) )
	{
		if ( defined( 'W3TC' ) )
		{
                    // Flush everything!
                    w3tc_flush_all();
		}
	}
}
add_action(  'transition_post_status',  'post_status', 10, 3 );

This simply clears every cache on the site when a custom post type is saved. Depending on the activity and traffic levels on your site, that might not be a great idea, so it’s wise to measure the performance of the site while editing content and make sure that repeated cache clearing doesn’t cause more server stress than not having caching enabled in the first place.

Profile picture of David Darke

David Darke

As the lead developer and co-founder at Atomic Smash. David’s wealth of knowledge in website development means that all sites work seamlessly across desktop, tablet and mobile devices.

Go back to top

Keep up to date with Atomic news